跳到主要內容

進階 Refine 檢查器

除了 集合原始 之外,更複雜的類型可以使用下列組合檢查器來建模。

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({});