Zod 常用方法
parse 系列
目前有几种 parse
方法:
parse
parseAsync
safeParse
safeParseAsync
两种大类:
parse
: 若 input 不符合 schema,则会抛出异常safeParse
: 若 input 不符合 schema,则会返回SafeParseError
,包含success
和error
两个字段
Examples:
ts
const schema = z.object({
name: z.string()
})
const user = schema.parse({ name: 1 }) // throw error!
const safeParseResult = schema.safeParse({ name: 1 })
// safeParseResult:
// if success: { success: true, data: user }
// else { success: false, error: ZodError }
coerce
coerce 可以理解为数据类型之间的强制转换,在日常开发中,可能会遇到:
- number <-> string
- date <-> string
coerce 支持以下几种类型:
string
number
bigint
boolean
date
Examples:
string -> number
ts
const toInt = z.coerce.number()
toInt.parse('123') // 123
number -> date
ts
const toDate = z.coerce.date()
toDate.parse(+new Date())
具体的转换规则如下:
ts
z.coerce.string() // String(input)
z.coerce.number() // Number(input)
z.coerce.boolean() // Boolean(input)
z.coerce.bigint() // BigInt(input)
z.coerce.date() // new Date(input)
Boolean 转换:
ts
z.coerce.boolean().parse('tuna') // => true
z.coerce.boolean().parse('true') // => true
z.coerce.boolean().parse('false') // => true
z.coerce.boolean().parse(1) // => true
z.coerce.boolean().parse([]) // => true
z.coerce.boolean().parse(0) // => false
z.coerce.boolean().parse(undefined) // => false
z.coerce.boolean().parse(null) // => false
refine
通过 refine
来自定义校验规则
refine 接收两个参数:
check
: 校验函数,返回boolean
/Promise<boolean>
message
: 校验失败时的提示信息,类型为string | CustomErrorParams | ((arg: Output) => CustomErrorParams)
Examples:
ts
const addressSchema = z.string().refine(val => val.length < 20, {
message: 'Address must be less than 20 characters'
})
const address = addressSchema.parse('12345678901234567890') // throws error
superRefine
提供了比 refine
更多的配置:
Examples:
ts
const Strings = z.array(z.string()).superRefine((val, ctx) => {
if (val.length > 3) {
ctx.addIssue({
code: z.ZodIssueCode.too_big,
maximum: 3,
type: 'array',
inclusive: true,
message: 'Too many items 😡',
})
}
if (val.length !== new Set(val).size) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'No duplicates allowed.',
})
}
})
可以通过 ctx.addIssue
来添加问题,如果在校验过程中此方法没有被调用,则说明校验通过。
默认情况下,整个校验过程不会停止,如果需要提前停止校验,可以通过 return Z.never
来实现:
Examples:
ts
const schema = z.number().superRefine((val, ctx) => {
if (val < 10) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'should be >= 10',
fatal: true,
})
return z.NEVER
}
if (val !== 12) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'should be twelve',
})
}
})
提高类型推导:
Examples:
ts
const schema = z
.object({
first: z.string(),
second: z.number(),
})
.nullable()
.superRefine((arg, ctx): arg is { first: string; second: number } => {
if (!arg) {
ctx.addIssue({
code: z.ZodIssueCode.custom, // customize your issue
message: 'object should exist',
})
}
return z.NEVER // The return value is not used, but we need to return something to satisfy the typing
})
// here, TS knows that arg is not null
.refine(arg => arg.first === 'bob', '`first` is not `bob`!')