本页面探讨了 Zod 中两种强大的模式组合机制:联合模式和交叉模式。虽然两者都能通过组合模式创建更复杂的验证模式,但它们的操作方式根本不同。
对于对象模式特有的组合方法,如 .extend()、.merge()、.pick() 和 .omit(),请参阅对象模式页面。
联合模式允许您创建一个接受与所提供任何模式匹配的值的模式。它们在内部实现为 ZodUnion 类。
有两种方法可以创建联合模式
两种方法都会创建相同类型的模式,但当基于现有模式构建时,.or() 方法可能更方便。
来源:README.md118-121 README.md884-888
当针对联合模式验证输入时,Zod 会执行以下操作:
ZodError模式的顺序很重要,因为 Zod 会返回第一个匹配模式的结果。如果您的模式存在重叠,请仔细考虑它们的顺序。
来源:src/__tests__/unions.test.ts22-33
联合模式通过 options 属性提供对其组成模式的访问
这对于对联合组件进行编程操作非常有用。
来源:src/__tests__/unions.test.ts51-57
当联合中的所有模式都无法验证输入时,Zod 需要决定报告哪些错误。它使用一种复杂的算法,该算法会:
实际上,这意味着您会收到最相关的错误消息,而不是一份令人困惑的输入失败方式列表。
来源:src/__tests__/unions.test.ts35-49
可辨别联合是一种特殊类型的联合模式,它针对包含一个通用“辨别属性”以确定其结构的对象进行了优化。
第一个参数是辨别属性的名称,第二个参数是对象模式数组。每个模式必须:
z.literal() 作为辨别值可辨别联合比普通联合更高效,因为它们会:
这使得可辨别联合在处理对象模式时比普通联合更高效、更用户友好。
与普通联合类似,您可以通过 options 属性访问组成模式。
要组合具有相同辨别属性的多个可辨别联合
交叉模式创建的模式要求值匹配所有提供的模式。它们对于组合验证要求特别有用。
有两种方法可以创建交叉模式
两种方法都会创建一个 ZodIntersection 模式,要求输入同时通过两个组成模式的验证。
当针对交叉模式验证输入时,Zod 会执行以下操作:
来源:src/__tests__/intersection.test.ts74-121
交叉模式最常见的用途是组合对象模式。结果要求同时包含两个模式的所有属性。
当交叉对象模式时,未知键的行为(严格、直通等)会继承自第二个(右侧)模式。
来源:src/__tests__/intersection.test.ts6-24
交叉模式通过递归合并其结构来处理深度嵌套的对象模式。
来源:src/__tests__/intersection.test.ts26-44
交叉模式也适用于数组,要求数组项满足所有模式。
来源:src/__tests__/intersection.test.ts46-72
并非所有模式都能有意义地交叉。当出现以下情况时,Zod 将抛出代码为 invalid_intersection_types 的错误:
来源:src/__tests__/intersection.test.ts74-121
| 组合器 | 何时使用 | 何时避免 |
|---|---|---|
| 联合 | 输入应匹配任意模式 | 您需要组合对象属性 |
| 可辨别联合 | 基于字段值的不同对象结构 | 对象不共享通用字段 |
| 交叉 | 输入必须满足所有模式 | 模式以不同方式转换数据 |
| 对象方法 (.extend, .merge) | 在对象上添加/组合属性 | 处理非对象模式 |