高级精炼检查器
除了 集合 和 基本类型 之外,可以使用以下组合检查器对更复杂的类型进行建模。
or()
验证一个值是否为两个给定检查器之一。
// define checker
const check = or(number(), array(string()));
// result type is correct
const value: number | $ReadOnlyArray<string> = check(1);
// test a value
assert(check(1).type === 'success');
assert(check(['one']).type === 'success');
assert(check(true).type === 'failure');
union()
or()
的泛化版本,可用于多个值。(注意:当前 flow 中存在限制,需要为 union
指定显式类型参数,因此需要单独的 or()
。)
// define checker
const check = union(number(), array(string()), bool());
// test a value
assert(check(1).type === 'success');
assert(check(['one']).type === 'success');
assert(check(true).type === 'success');
assert(check([1]).type === 'failure');
lazy()
:递归集合
lazy()
实用程序允许定义递归检查器。
const Person = object({
name: string(),
friends: nullable(array(lazy(() => Person))),
});
const result = Person({name: 'alice', friends: [{name: 'bob'}]});
// should succeed to validate
assert(result.type === 'success');
警告:值中的递归引用将无法工作,因为检查器会发生堆栈溢出。
const Person = object({
name: string(),
friends: nullable(array(lazy(() => Person))),
});
const alice = {name: 'alice', friends: []};
// add self to own friends
alice.friends.push(alice);
// Error: will stack overflow
Person(alice);
自定义类型
custom()
custom
实用程序使定义快速自定义类型(如类)变得很简单。
警告:不要将此用于需要类型参数的类(如 MyClass<T>
,因为无法通过 instanceof 验证类型参数是否正确)。
class MyClass {}
function myClass(): Checker<MyClass> {
return custom(
value => value instanceof MyClass ? value : null,
'value is not a valid instance of MyClass'
);
}
const check = array(myClass());
assert(check([new MyClass()]).type === 'success');
assert(check([3]).type === 'failure');
asType()
asType()
将从一种类型转换为另一种类型。提供预期类型的检查器和回调函数以转换为不同的输出类型。例如,您可以使用此方法将值强制转换为不透明类型。
opaque type ID = string;
const IDChecker: Checker<ID> = asType(string(), s => (s: ID));
match()
此检查器只是 union
的别名,它将所有输入检查器限制为生成相同的输出类型。
使用 match()
和 asType()
,您可以从以前的类型升级到最新版本。
const myChecker: Checker<{str: string}> = match(
object({str: string()}),
asType(string(), str => ({str: str})),
asType(number(), num => ({str: String(num)})),
);
const obj1: {str: string} = coercion(myChecker({str: 'hello'}));
const obj2: {str: string} = coercion(myChecker('hello'));
const obj3: {str: string} = coercion(myChecker(123));
constraint()
如果您希望要求值通过逻辑谓词,则可以使用 constraint()
。
const evenNumber = constraint(
number(),
n => n % 2 === 0
);
const passes = evenNumber(2);
// passes.type === 'success';
const fails = evenNumber(1);
// fails.type === 'failure';
withDefault()
一个检查器,如果提供的值为可空,则提供一个 withDefault()
值。
const objPropertyWithDefault = object({
foo: withDefault(number(), 123),
});
// result will be `{foo: 123}`.
const result = check({});