Other
这份指南解释了其他特殊的模式函数,例如 literal、instance、custom 和 lazy,这些函数没有在其他指南中涵盖。
literal 模式
你可以使用 literal 来定义一个模式,它匹配特定的字符串、数字或布尔值。因此,这种模式非常适合表示字面量类型。用法很简单,只需将你想要匹配的值作为第一个参数传入即可。
import * as v from 'valibot';
const StringLiteralSchema = v.literal('foo'); // 'foo'
const NumberLiteralSchema = v.literal(12345); // 12345
const BooleanLiteralSchema = v.literal(true); // true
instance 模式
通过 blob、date、map 和 set 等模式函数,Valibot 已经涵盖了最常见的 JavaScript 类。然而,可能还有很多你想要验证的类。为此,你可以使用 instance 模式函数。它将一个类作为第一个参数,并返回一个只匹配该类实例的模式。
import * as v from 'valibot';
const ErrorSchema = v.instance(Error); // Error
const UrlSchema = v.instance(URL); // URL
custom 模式
custom 模式函数稍微高级一些。它允许你根据一个自定义函数来定义一个匹配某个值的模式。当你需要定义一个无法用其他模式函数表达的模式时,就可以使用它。
这个函数接收要验证的值作为它的第一个参数,并且必须返回一个布尔值。如果函数返回 true,则该值被认为是有效的。否则,它被认为是无效的。
import * as v from 'valibot';
const PixelStringSchema = v.custom<`${number}px`>((input) =>
typeof input === 'string' ? /^\d+px$/.test(input) : false);
lazy 模式
lazy 模式函数允许你定义递归模式。递归模式是引用自身的模式。例如,你可以用它来定义一个树状数据结构的模式。
由于 TypeScript 的限制,在这种情况下输入和输出类型无法自动推断。因此,你必须使用 GenericSchema 类型来显式指定这些类型。
import * as v from 'valibot';
type BinaryTree = {
element: string;
left: BinaryTree | null;
right: BinaryTree | null;
};
const BinaryTreeSchema: v.GenericSchema<BinaryTree> = v.object({
element: v.string(),
left: v.nullable(v.lazy(() => BinaryTreeSchema)),
right: v.nullable(v.lazy(() => BinaryTreeSchema)),
});
lazy 的另一个实际用例是为所有可能的 JSON 值定义模式。这些值是所有可以使用 JSON.stringify() 和 JSON.parse() 进行序列化和反序列化的值。
import * as v from 'valibot';
type JsonData =
| string
| number
| boolean
| null
| { [key: string]: JsonData }
| JsonData[];
const JsonSchema: v.GenericSchema<JsonData> = v.lazy(() =>
v.union([
v.string(),
v.number(),
v.boolean(),
v.null(),
v.record(v.string(), JsonSchema),
v.array(JsonSchema),
]));