Skip to content
On this page

Zod 常用方法

parse 系列

目前有几种 parse 方法:

  • parse
  • parseAsync
  • safeParse
  • safeParseAsync

两种大类:

  • parse: 若 input 不符合 schema,则会抛出异常
  • safeParse: 若 input 不符合 schema,则会返回 SafeParseError,包含 successerror 两个字段

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`!')