定义模式
要验证数据,必须首先定义一个模式。Schema 表示各种类型,从简单的原始值到复杂的嵌套对象和数组。
¥To validate data, you must first define a schema. Schemas represent types, from simple primitive values to complex nested objects and arrays.
原语
¥Primitives
强制转换
¥Coercion
要将输入数据强制转换为适当的类型,请改用 z.coerce
:
¥To coerce input data to the appropriate type, use z.coerce
instead:
这些模式的强制类型会尝试将输入值转换为适当的类型。
¥The coerced variant of these schemas attempts to convert the input value to the appropriate type.
字面量
¥Literals
字面量模式代表 字面类型,例如 "hello world"
或 5
。
¥Literal schemas represent a literal type, like "hello world"
or 5
.
要表示 JavaScript 字面量 null
和 undefined
:
¥To represent the JavaScript literals null
and undefined
:
要允许多个字面量值:
¥To allow multiple literal values:
要从字面模式中提取允许值的集合:
¥To extract the set of allowed values from a literal schema:
字符串
¥Strings
Zod 提供了一些内置的字符串验证和转换 API。要执行一些常见的字符串验证:
¥Zod provides a handful of built-in string validation and transform APIs. To perform some common string validations:
要执行一些简单的字符串转换:
¥To perform some simple string transforms:
字符串格式
¥String formats
要针对某些常见字符串格式进行验证:
¥To validate against some common string formats:
电子邮件
¥Emails
要验证电子邮件地址:
¥To validate email addresses:
默认情况下,Zod 使用一个相对严格的电子邮件正则表达式,用于验证包含常见字符的普通电子邮件地址。它大致相当于 Gmail 强制执行的规则。要了解有关此正则表达式的更多信息,请参阅 此文章。
¥By default, Zod uses a comparatively strict email regex designed to validate normal email addresses containing common characters. It's roughly equivalent to the rules enforced by Gmail. To learn more about this regex, refer to this post.
要自定义电子邮件验证行为,可以将自定义正则表达式传递给 pattern
参数。
¥To customize the email validation behavior, you can pass a custom regular expression to the pattern
param.
Zod 导出了几个你可以使用的有用的正则表达式。
¥Zod exports several useful regexes you could use.
UUIDs
要验证 UUID:
¥To validate UUIDs:
要指定特定的 UUID 版本:
¥To specify a particular UUID version:
RFC 9562/4122 UUID 规范要求第 8 个字节的前两位为 10
。其他类似 UUID 的标识符不强制执行此约束。要验证任何类似 UUID 的标识符:
¥The RFC 9562/4122 UUID spec requires the first two bits of byte 8 to be 10
. Other UUID-like identifiers do not enforce this constraint. To validate any UUID-like identifier:
URLs
要验证任何与 WHATWG 兼容的 URL:
¥To validate any WHATWG-compatible URL:
正如你所见,这相当宽松。在内部,这将使用 new URL()
构造函数来验证输入;此行为可能因平台和运行时而异,但它是在任何给定的 JS 运行时/引擎上验证 URI/URL 最严格的方法。
¥As you can see this is quite permissive. Internally this uses the new URL()
constructor to validate inputs; this behavior may differ across platforms and runtimes but it's the mostly rigorous way to validate URIs/URLs on any given JS runtime/engine.
要根据特定的正则表达式验证主机名:
¥To validate the hostname against a specific regex:
要根据特定的正则表达式验证协议,请使用 protocol
参数。
¥To validate the protocol against a specific regex, use the protocol
param.
Web URL — 在许多情况下,你需要专门验证 Web URL。以下是推荐的架构:
¥Web URLs — In many cases, you'll want to validate Web URLs specifically. Here's the recommended schema for doing so:
这将协议限制为 http
/https
,并确保主机名是使用 z.regexes.domain
正则表达式的有效域名:
¥This restricts the protocol to http
/https
and ensures the hostname is a valid domain name with the z.regexes.domain
regular expression:
ISO 日期时间
¥ISO datetimes
你可能已经注意到,Zod 字符串包含一些与日期/时间相关的验证。这些验证基于正则表达式,因此它们不像完整的日期/时间库那样严格。但是,它们对于验证用户输入非常方便。
¥As you may have noticed, Zod string includes a few date/time related validations. These validations are regular expression based, so they are not as strict as a full date/time library. However, they are very convenient for validating user input.
z.iso.datetime()
方法强制执行 ISO 8601 标准;默认情况下,不允许使用时区偏移:
¥The z.iso.datetime()
method enforces ISO 8601; by default, no timezone offsets are allowed:
要允许时区偏移:
¥To allow timezone offsets:
要允许非限定(无时区)日期时间:
¥To allow unqualified (timezone-less) datetimes:
限制允许时间 precision
。默认情况下,秒是可选的,允许任意亚秒级精度。
¥To constrain the allowable time precision
. By default, seconds are optional and arbitrary sub-second precision is allowed.
ISO 日期
¥ISO dates
z.iso.date()
方法验证 YYYY-MM-DD
格式的字符串。
¥The z.iso.date()
method validates strings in the format YYYY-MM-DD
.
ISO 时间
¥ISO times
z.iso.time()
方法验证 HH:MM[:SS[.s+]]
格式的字符串。默认情况下,秒是可选的,亚秒级精度也是可选的。
¥The z.iso.time()
method validates strings in the format HH:MM[:SS[.s+]]
. By default seconds are optional, as are sub-second deciams.
不允许任何形式的偏移。
¥No offsets of any kind are allowed.
使用 precision
参数来限制允许的小数精度。
¥Use the precision
parameter to constrain the allowable decimal precision.
IP 地址
¥IP addresses
IP 地址块 (CIDR)
¥IP blocks (CIDR)
验证使用 CIDR 表示法 指定的 IP 地址范围。
¥Validate IP address ranges specified with CIDR notation.
模板字面量
¥Template literals
Zod 4 中的新功能
¥New in Zod 4
定义一个模板字面量模式:
¥To define a template literal schema:
z.templateLiteral
API 可以处理任意数量的字符串字面量(例如 "hello"
)和模式。任何具有可赋值给 string | number | bigint | boolean | null | undefined
的推断类型的 Schema 都可以传递。
¥The z.templateLiteral
API can handle any number of string literals (e.g. "hello"
) and schemas. Any schema with an inferred type that's assignable to string | number | bigint | boolean | null | undefined
can be passed.
数字
¥Numbers
使用 z.number()
验证数字。它允许任意有限数字。
¥Use z.number()
to validate numbers. It allows any finite number.
Zod 实现了一些特定于数字的验证:
¥Zod implements a handful of number-specific validations:
如果(出于某种原因)你想要验证 NaN
,请使用 z.nan()
。
¥If (for some reason) you want to validate NaN
, use z.nan()
.
整数
¥Integers
要验证整数:
¥To validate integers:
BigInts
要验证 BigInt:
¥To validate BigInts:
Zod 包含一些特定于 bigint 的验证。
¥Zod includes a handful of bigint-specific validations.
布尔值
¥Booleans
要验证布尔值:
¥To validate boolean values:
日期
¥Dates
使用 z.date()
验证 Date
实例。
¥Use z.date()
to validate Date
instances.
要自定义错误消息:
¥To customize the error message:
Zod 提供了一些特定于日期的验证。
¥Zod provides a handful of date-specific validations.
枚举
¥Enums
使用 z.enum
根据一组固定的允许字符串值验证输入。
¥Use z.enum
to validate inputs against a fixed set of allowable string values.
注意 - 如果将字符串数组声明为变量,Zod 将无法正确推断每个元素的确切值。
¥Careful — If you declare your string array as a variable, Zod won't be able to properly infer the exact values of each element.
要解决此问题,请始终将数组直接传递给 z.enum()
函数,或使用 as const
。
¥To fix this, always pass the array directly into the z.enum()
function, or use as const
.
你还可以传入外部声明的 TypeScript 枚举。
¥You can also pass in an externally-declared TypeScript enum.
Zod 4 — 这将取代 Zod 3 中的 z.nativeEnum()
API。
¥Zod 4 — This replaces the z.nativeEnum()
API in Zod 3.
请注意,使用 TypeScript 的 enum
关键字会得到 不推荐。
¥Note that using TypeScript's enum
keyword is not recommended.
.enum
要将模式的值提取为类似枚举的对象:
¥To extract the schema's values as an enum-like object:
.exclude()
要创建新的枚举架构并排除某些值:
¥To create a new enum schema, excluding certain values:
.extract()
要创建新的枚举架构并提取某些值:
¥To create a new enum schema, extracting certain values:
字符串布尔值
¥Stringbools
💎 Zod 4 中的新功能
¥💎 New in Zod 4
在某些情况下(例如解析环境变量),将某些字符串 "boolish" 值解析为普通的 boolean
值很有价值。为了支持这一点,Zod 4 引入了 z.stringbool()
:
¥In some cases (e.g. parsing environment variables) it's valuable to parse certain string "boolish" values to a plain boolean
value. To support this, Zod 4 introduces z.stringbool()
:
自定义真值和假值:
¥To customize the truthy and falsy values:
默认情况下,Schema 不区分大小写;所有输入在与 truthy
/falsy
值进行比较之前都会转换为小写。要使其区分大小写:
¥Be default the schema is case-insensitive; all inputs are converted to lowercase before comparison to the truthy
/falsy
values. To make it case-sensitive:
可选值
¥Optionals
要使架构可选(即允许 undefined
输入)。
¥To make a schema optional (that is, to allow undefined
inputs).
这将返回一个封装原始模式的 ZodOptional
实例。要提取内部模式:
¥This returns a ZodOptional
instance that wraps the original schema. To extract the inner schema:
可空值
¥Nullables
要使架构可空(即允许 null
输入)。
¥To make a schema nullable (that is, to allow null
inputs).
这将返回一个封装原始模式的 ZodNullable
实例。要提取内部模式:
¥This returns a ZodNullable
instance that wraps the original schema. To extract the inner schema:
将空值转换为空值
¥Nullish
要使架构可空(可选且可空):
¥To make a schema nullish (both optional and nullable):
记录变得更加智能。
¥Refer to the TypeScript manual for more about the concept of nullish.
未知
¥Unknown
Zod 旨在一对一地镜像 TypeScript 的类型系统。因此,Zod 提供了 API 来表示以下特殊类型:
¥Zod aims to mirror TypeScript's type system one-to-one. As such, Zod provides APIs to represent the following special types:
从不
¥Never
任何值都无法通过验证。
¥No value will pass validation.
对象
¥Objects
定义一个对象类型:
¥To define an object type:
默认情况下,所有属性都是必需的。要使某些属性可选:
¥By default, all properties are required. To make certain properties optional:
默认情况下,无法识别的键将从解析结果中剥离:
¥By default, unrecognized keys are stripped from the parsed result:
z.strictObject
定义一个在发现未知键时抛出错误的严格模式:
¥To define a strict schema that throws an error when unknown keys are found:
z.looseObject
定义一个允许未知键通过的宽松模式:
¥To define a loose schema that allows unknown keys to pass through:
.catchall()
要定义一个用于验证任何无法识别的键的通用模式:
¥To define a catchall schema that will be used to validate any unrecognized keys:
.shape
访问内部模式:
¥To access the internal schemas:
.keyof()
要从对象架构的键创建 ZodEnum
架构:
¥To create a ZodEnum
schema from the keys of an object schema:
.extend()
要向对象架构添加其他字段:
¥To add additional fields to an object schema:
此 API 可用于覆盖现有字段!小心使用这种能力!如果两个模式共享密钥,则 B 将覆盖 A。
¥This API can be used to overwrite existing fields! Be careful with this power! If the two schemas share keys, B will override A.
替代方案:解构 - 你也可以通过创建一个全新的对象模式来完全避免使用 .extend()
。这使得生成的 schema 的严格级别在视觉上显而易见。
¥Alternative: destructuring — You can alternatively avoid .extend()
altogether by creating a new object schema entirely. This makes the strictness level of the resulting schema visually obvious.
你也可以使用此功能一次性合并多个对象。
¥You can also use this to merge multiple objects in one go.
这种方法有几个优点:
¥This approach has a few advantages:
-
它使用语言级功能 (解构语法),而非特定于库的 API
¥It uses language-level features (destructuring syntax) instead of library-specific APIs
-
相同的语法适用于 Zod 和 Zod Mini
¥The same syntax works in Zod and Zod Mini
-
它更高效地执行
tsc
操作 -.extend()
方法在大型架构上可能开销较大,而由于 TypeScript 的限制 的原因,当调用链式调用时,开销会呈二次方增长。¥It's more
tsc
-efficient — the.extend()
method can be expensive on large schemas, and due to a TypeScript limitation it gets quadratically more expensive when calls are chained -
如果你愿意,可以使用
z.strictObject()
或z.looseObject()
更改生成模式的严格级别。¥If you wish, you can change the strictness level of the resulting schema by using
z.strictObject()
orz.looseObject()
.pick()
受 TypeScript 内置 Pick
和 Omit
工具类型的启发,Zod 提供了专用 API,用于从对象模式中选择和省略某些键。
¥Inspired by TypeScript's built-in Pick
and Omit
utility types, Zod provides dedicated APIs for picking and omitting certain keys from an object schema.
从此初始模式开始:
¥Starting from this initial schema:
要选择某些键:
¥To pick certain keys:
.omit()
要省略某些键:
¥To omit certain keys:
.partial()
为了方便起见,Zod 提供了一个专用 API,用于将部分或全部属性设为可选属性,其灵感来自内置的 TypeScript 工具类型 Partial
。
¥For convenience, Zod provides a dedicated API for making some or all properties optional, inspired by the built-in TypeScript utility type Partial
.
要使所有字段可选:
¥To make all fields optional:
要使某些属性可选:
¥To make certain properties optional:
.required()
Zod 提供了一个 API,用于将部分或所有属性设为必需,这受到了 TypeScript 的 Required
工具类型的启发。
¥Zod provides an API for making some or all properties required, inspired by TypeScript's Required
utility type.
要使所有属性必填:
¥To make all properties required:
要使某些属性成为必需属性:
¥To make certain properties required:
递归对象
¥Recursive objects
定义一个自引用类型,在键上使用 getter。这允许 JavaScript 在运行时解析循环模式。
¥To define a self-referential type, use a getter on the key. This lets JavaScript resolve the cyclical schema at runtime.
虽然支持递归 schema,但将循环数据传递给 Zod 会导致无限循环。
¥Though recursive schemas are supported, passing cyclical data into Zod will cause an infinite loop.
你还可以表示相互递归的类型:
¥You can also represent mutually recursive types:
所有对象 API(.pick()
、.omit()
、.required()
、.partial()
等)均按预期工作。
¥All object APIs (.pick()
, .omit()
, .required()
, .partial()
, etc.) work as you'd expect.
循环错误
¥Circularity errors
由于 TypeScript 的限制,递归类型推断可能比较复杂,并且仅在特定场景下有效。一些更复杂的类型可能会触发递归类型错误,如下所示:
¥Due to TypeScript limitations, recursive type inference can be finicky, and it only works in certain scenarios. Some more complicated types may trigger recursive type errors like this:
在这些情况下,你可以在有问题的 getter 上添加类型注释来解析错误:
¥In these cases, you can resolve the error with a type annotation on the offending getter:
数组
¥Arrays
定义一个数组模式:
¥To define an array schema:
访问数组元素的内部模式。
¥To access the inner schema for an element of the array.
Zod 实现了一些特定于数组的验证:
¥Zod implements a number of array-specific validations:
元组
¥Tuples
与数组不同,元组通常是固定长度的数组,每个索引指定不同的模式。
¥Unlike arrays, tuples are typically fixed-length arrays that specify different schemas for each index.
要添加可变参数 ("rest"):
¥To add a variadic ("rest") argument:
联合
¥Unions
联合类型 (A | B
) 表示逻辑上的 "OR"。Zod 联合模式将按顺序根据每个选项检查输入。返回第一个验证成功的值。
¥Union types (A | B
) represent a logical "OR". Zod union schemas will check the input against each option in order. The first value that validates successfully is returned.
要提取内部选项模式:
¥To extract the internal option schemas:
可区分联合
¥Discriminated unions
可区分联合 是一种特殊的联合,其中 a) 所有选项都是对象模式,并且 b) 共享一个特定的键("discriminator")。根据 discriminator 键的值,TypeScript 能够如你所愿对类型签名进行 "narrow" 验证。
¥A discriminated union is a special kind of union in which a) all the options are object schemas that b) share a particular key (the "discriminator"). Based on the value of the discriminator key, TypeScript is able to "narrow" the type signature as you'd expect.
你可以使用常规的 z.union()
来表示它。但常规的联合操作比较简单 - 它们按顺序根据每个选项检查输入,并返回第一个通过的选项。对于大型联合来说,这可能会很慢。
¥You could represent it with a regular z.union()
. But regular unions are naive—they check the input against each option in order and return the first one that passes. This can be slow for large unions.
因此,Zod 提供了一个使用鉴别键的 z.discriminatedUnion()
API,以提高解析效率。
¥So Zod provides a z.discriminatedUnion()
API that uses a discriminator key to make parsing more efficient.
交叉点
¥Intersections
交叉类型 (A & B
) 表示逻辑上的 "AND"。
¥Intersection types (A & B
) represent a logical "AND".
这对于交叉两种对象类型很有用。
¥This can be useful for intersecting two object types.
合并对象模式时,优先使用 A.extend(B)
而不是交集。使用 .extend()
将为你提供一个新的对象 schema,而 z.intersection(A, B)
将返回一个 ZodIntersection
实例,它缺少像 pick
和 omit
这样的通用对象方法。
¥When merging object schemas, prefer A.extend(B)
over intersections. Using .extend()
will gve you a new object schema, whereas z.intersection(A, B)
returns a ZodIntersection
instance which lacks common object methods like pick
and omit
.
记录
¥Records
阅读 Record<string, number>
了解更多信息。
¥Record schemas are used to validate types such as Record<string, number>
.
键模式可以是任何可分配给 string | number | symbol
的 Zod 模式。
¥The key schema can be any Zod schema that is assignable to string | number | symbol
.
要创建包含枚举定义的键的对象架构:
¥To create an object schemas containing keys defined by an enum:
Zod 4 — 在 Zod 4 中,如果你将 z.enum
作为 z.record()
的第一个参数传递,Zod 将全面检查输入中所有枚举值是否作为键存在。此行为与 TypeScript 一致:
¥Zod 4 — In Zod 4, if you pass a z.enum
as the first argument to z.record()
, Zod will exhaustively check that all enum values exist in the input as keys. This behavior agrees with TypeScript:
在 Zod 3 中,未进行详尽性检查。要复制旧行为,请使用 z.partialRecord()
。
¥In Zod 3, exhaustiveness was not checked. To replicate the old behavior, use z.partialRecord()
.
如果你需要部分记录类型,请使用 z.partialRecord()
。这将跳过 Zod 通常使用 z.enum()
和 z.literal()
密钥模式运行的特殊详尽性检查。
¥If you want a partial record type, use z.partialRecord()
. This skips the special exhaustiveness checks Zod normally runs with z.enum()
and z.literal()
key schemas.
映射
¥Maps
集合
¥Sets
可以使用以下实用方法进一步约束设置的 Schema。
¥Set schemas can be further constrained with the following utility methods.
文件
¥Files
要验证 File
实例:
¥To validate File
instances:
Promise
已弃用 — z.promise()
在 Zod 4 中已弃用。Promise
模式的有效用例极其有限。如果你怀疑某个值可能是 Promise
,只需在使用 Zod 解析之前对其进行 await
转换即可。
¥Deprecated — z.promise()
is deprecated in Zod 4. There are vanishingly few valid uses cases for a Promise
schema. If you suspect a value might be a Promise
, simply await
it before parsing it with Zod.
Instanceof
你可以使用 z.instanceof
检查输入是否是某个类的实例。这对于针对从第三方库导出的类验证输入非常有用。
¥You can use z.instanceof
to check that the input is an instance of a class. This is useful to validate inputs against classes that are exported from third-party libraries.
细化
¥Refinements
每个 Zod 模式都存储一个改进数组。细化是一种执行自定义验证的方法,Zod 并未提供原生 API。
¥Every Zod schema stores an array of refinements. Refinements are a way to perform custom validation that Zod doesn't provide a native API for.
.refine()
细化函数不应该抛出异常。它们应该返回一个假值来表示失败。Zod 无法捕获抛出的错误。
¥Refinement functions should never throw. Instead they should return a falsy value to signal failure. Thrown errors are not caught by Zod.
error
要自定义错误消息:
¥To customize the error message:
abort
默认情况下,检查中的验证问题被认为是可继续的;也就是说,Zod 将按顺序执行所有检查,即使其中一个检查导致验证错误。这通常是可取的,因为这意味着 Zod 可以一次性显示尽可能多的错误。
¥By default, validation issues from checks are considered continuable; that is, Zod will execute all checks in sequence, even if one of them causes a validation error. This is usually desirable, as it means Zod can surface as many errors as possible in one go.
要将特定细化标记为不连续,请使用 abort
参数。如果检查失败,验证将终止。
¥To mark a particular refinement as non-continuable, use the abort
parameter. Validation will terminate if the check fails.
path
要自定义错误路径,请使用 path
参数。这通常仅在对象模式的上下文中有用。
¥To customize the error path, use the path
parameter. This is typically only useful in the context of object schemas.
这将在相关问题中设置 path
参数:
¥This will set the path
parameter in the associated issue:
要定义异步优化,只需传递一个 async
函数:
¥To define an asynchronous refinement, just pass an async
function:
如果你使用异步细化,则必须使用 .parseAsync
方法来解析数据!否则 Zod 将抛出错误。
¥If you use async refinements, you must use the .parseAsync
method to parse data! Otherwise Zod will throw an error.
when
注意 — 这是一项高级用户功能,绝对可能被滥用,从而增加源自改进内部的未捕获错误的概率。
¥— This is a power user feature and can absolutely be abused in ways that will increase the probability of uncaught errors originating from inside your refinements.
默认情况下,如果已经遇到任何不可持续的问题,则不会运行细化。Zod 在将值传递给任何细化函数之前,会仔细确保其类型签名正确无误。
¥By default, refinements don't run if any non-continuable issues have already been encountered. Zod is careful to ensure the type signature of the value is correct before passing it into any refinement functions.
在某些情况下,你希望更精细地控制优化运行的时间。例如,请考虑以下 "密码确认" 检查:
¥In some cases, you want finer control over when refinements run. For instance consider this "password confirm" check:
anotherField
上的错误将阻止密码确认检查的执行,即使该检查不依赖于 anotherField
。要控制优化的运行时间,请使用 when
参数:
¥An error on anotherField
will prevent the password confirmation check from executing, even though the check doesn't depend on anotherField
. To control when a refinement will run, use the when
parameter:
.superRefine()
在 Zod 4 中,.superRefine()
已被弃用,取而代之的是 .check()
。
¥In Zod 4, .superRefine()
has been deprecated in favor of .check()
.check()
.refine()
API 是更通用(且冗长)的 API .check()
上的语法糖。你可以使用此 API 在单个细化中创建多个问题,或者完全控制生成的问题对象。
¥The .refine()
API is syntactic sugar atop a more versatile (and verbose) API called .check()
. You can use this API to create multiple issues in a single refinement or have full control of the generated issue objects.
常规 .refine
API 仅会生成带有 "custom"
错误代码的问题,但 .check()
可以抛出其他类型的问题。有关 Zod 内部问题类型的更多信息,请阅读 错误自定义 文档。
¥The regular .refine
API only generates issues with a "custom"
error code, but .check()
makes it possible to throw other issue types. For more information on Zod's internal issue types, read the Error customization docs.
管道
¥Pipes
Schema 可以链接在一起形成 "pipes"。管道主要在与 转换 结合使用时有用。
¥Schemas can be chained together into "pipes". Pipes are primarily useful when used in conjunction with Transforms.
转换
¥Transforms
转换是一种特殊的模式。它们不再验证输入,而是接受任何数据并对数据执行某种转换。要定义转换:
¥Transforms are a special kind of schema. Instead of validating input, they accept anything and perform some transformation on the data. To define a transform:
要在转换内部执行验证逻辑,请使用 ctx
。要报告验证问题,请将新问题推送到 ctx.issues
(类似于 .check()
API)。
¥To perform validation logic inside a transform, use ctx
. To report a validation issue, push a new issue onto ctx.issues
(similar to the .check()
API).
通常,转换操作与 管道 结合使用。这种组合对于执行一些初始验证,然后将解析后的数据转换为另一种形式非常有用。
¥Most commonly, transforms are used in conjunction with Pipes. This combination is useful for performing some initial validation, then transforming the parsed data into another form.
.transform()
将某些模式通过管道传输到转换中是一种常见的模式,因此 Zod 提供了一种便捷的 .transform()
方法。
¥Piping some schema into a transform is a common pattern, so Zod provides a convenience .transform()
method.
转换也可以是异步的:
¥Transforms can also be async:
如果你使用异步转换,则解析数据时必须使用 .parseAsync
或 .safeParseAsync
!否则 Zod 将抛出错误。
¥If you use async transforms, you must use a .parseAsync
or .safeParseAsync
when parsing data! Otherwise Zod will throw an error.
.preprocess()
将转换通过管道传输到另一个模式是另一种常见模式,因此 Zod 提供了一个便捷的 z.preprocess()
函数。
¥Piping a transform into another schema is another common pattern, so Zod provides a convenience z.preprocess()
function.
默认值
¥Defaults
要设置模式的默认值:
¥To set a default value for a schema:
或者,你可以传递一个函数,每当需要生成默认值时,该函数都会重新执行:
¥Alternatively, you can pass a function which will be re-executed whenever a default value needs to be generated:
预错误
¥Prefaults
在 Zod 中,设置默认值将缩短解析过程。如果输入是 undefined
,则立即返回默认值。因此,默认值必须可以赋值给 Schema 的输出类型。
¥In Zod, setting a default value will short-circuit the parsing process. If the input is undefined
, the default value is eagerly returned. As such, the default value must be assignable to the output type of the schema.
有时,定义一个预故障 ("预解析默认值") 值很有用。如果输入是 undefined
,则将解析预设值。解析过程没有短路。因此,默认值必须可以赋值给 Schema 的输入类型。
¥Sometimes, it's useful to define a prefault ("pre-parse default") value. If the input is undefined
, the prefault value will be parsed instead. The parsing process is not short circuited. As such, the prefault value must be assignable to the input type of the schema.
如果你想通过一些可变的改进传递一些输入值,这也很有用。
¥This is also useful if you want to pass some input value through some mutating refinements.
捕获
¥Catch
使用 .catch()
定义在发生验证错误时返回的后备值:
¥Use .catch()
to define a fallback value to be returned in the event of a validation error:
或者,你可以传递一个函数,每当需要生成捕获值时,该函数都会重新执行。
¥Alternatively, you can pass a function which will be re-executed whenever a catch value needs to be generated.
品牌类型
¥Branded types
TypeScript 的类型系统是 structural,这意味着两个结构等效的类型被视为相同。
¥TypeScript's type system is structural, meaning that two types that are structurally equivalent are considered the same.
在某些情况下,可能需要在 TypeScript 中模拟 名义类型。这可以通过品牌类型(也称为 "不透明类型")实现。
¥In some cases, it can be desirable to simulate nominal typing inside TypeScript. This can be achieved with branded types (also known as "opaque types").
在底层,这是通过将 "brand" 附加到架构的推断类型来实现的。
¥Under the hood, this works by attaching a "brand" to the schema's inferred type.
使用此品牌,任何普通(无品牌)数据结构都不再可分配给推断的类型。你必须使用模式解析一些数据才能获得品牌数据。
¥With this brand, any plain (unbranded) data structures are no longer assignable to the inferred type. You have to parse some data with the schema to get branded data.
请注意,品牌类型不会影响 .parse
的运行时结果。它是一个纯静态的构造函数。
¥Note that branded types do not affect the runtime result of .parse
. It is a static-only construct.
只读
¥Readonly
要将模式标记为只读:
¥To mark a schema as readonly:
新模式的推断类型将标记为 readonly
。请注意,在 TypeScript 中,这仅影响对象、数组、元组、Set
和 Map
:
¥The inferred type of the new schemas will be marked as readonly
. Note that in TypeScript, this only affects objects, arrays, tuples, Set
, and Map
:
输入将像平常一样进行解析,然后结果将使用 Object.freeze()
进行冻结,以防止修改。
¥Inputs will be parsed like normal, then the result will be frozen with Object.freeze()
to prevent modifications.
JSON
要验证任何可 JSON 编码的值:
¥To validate any JSON-encodable value:
这是一个便捷的 API,它返回以下联合模式:
¥This is a convenience API that returns the following union schema:
自定义
¥Custom
你可以使用 z.custom()
为任何 TypeScript 类型创建 Zod 模式。这对于为 Zod 不支持的类型创建模式(例如模板字符串字面量)非常有用。
¥You can create a Zod schema for any TypeScript type by using z.custom()
. This is useful for creating schemas for types that are not supported by Zod out of the box, such as template string literals.
如果你不提供验证函数,Zod 将允许任何值。这可能很危险!
¥If you don't provide a validation function, Zod will allow any value. This can be dangerous!
你可以通过传递第二个参数来自定义错误消息和其他选项。此参数的工作方式与 .refine
的 params 参数相同。
¥You can customize the error message and other options by passing a second argument. This parameter works the same way as the params parameter of .refine
.
函数
¥Functions
在 Zod 4 中,z.function()
不再返回 Zod 模式。
¥In Zod 4, z.function()
no longer returns a Zod schema.
Zod 提供了一个 z.function()
实用程序,用于定义经过 Zod 验证的函数。这样,你可以避免将验证代码与业务逻辑混合在一起。
¥Zod provides a z.function()
utility for defining Zod-validated functions. This way, you can avoid intermixing validation code with your business logic.
函数 Schema 有一个 .implement()
方法,它接受一个函数并返回一个新函数,该函数会自动验证其输入和输出。
¥Function schemas have an .implement()
method which accepts a function and returns a new function that automatically validates its inputs and outputs.
如果输入无效,此函数将抛出 ZodError
:
¥This function will throw a ZodError
if the input is invalid:
如果你只关心验证输入,则可以省略 output
字段。
¥If you only care about validating inputs, you can omit the output
field.