本文档介绍了 Zod 的转换功能,它允许您在验证过程中修改数据。转换提供了一种强大的方式来改变数据的形状或类型,同时保持类型安全。有关不改变数据类型进行精炼的信息,请参阅精炼。
Zod 中的转换允许您将一种类型的输入转换为可能不同类型的输出。与仅验证数据而不改变其类型的精炼不同,转换可以完全修改数据结构。
来源:src/types.ts508-517 README.md147-152
每个 Zod 模式都有一个 .transform() 方法,该方法接受一个函数来转换已验证的数据
来源:src/types.ts508-517 src/__tests__/transformer.test.ts95-101
transform 方法接受一个函数,该函数接收成功验证的数据并返回一个新值
结果是一个新的模式,其输出类型是从 transform 函数的返回类型推断出来的。
来源:src/__tests__/transformer.test.ts8 src/__tests__/transformer.test.ts95-101
Zod 中的转换通过一种特殊的模式类型实现,称为 ZodEffects。当您在一个模式上调用 .transform() 时,它会返回一个新的 ZodEffects 模式,该模式包装了原始模式。
当一个带有转换的模式被解析时,会发生以下过程
来源:src/types.ts508-517 src/__tests__/transformer.test.ts199-215
您可以链式调用多个 transform 来执行序列转换。每个转换步骤都按照它们定义的顺序应用。
来源:src/__tests__/transformer.test.ts193-197
Zod 自动推断转换后模式的输入和输出类型
这种类型推断在具有转换属性的复杂对象中特别有用
来源:src/__tests__/transformer.test.ts173-183
transform 函数接收第二个参数 ctx (上下文),它允许您在转换期间添加验证问题
当使用 ctx.addIssue() 时,您应该返回特殊的 z.NEVER 符号,以表明转换失败,这保留了正确的类型推断。
来源:src/__tests__/transformer.test.ts13-42 src/__tests__/transformer.test.ts76-93
通过返回 Promise,转换可以是异步的。异步转换必须使用 parseAsync 或 safeParseAsync 进行解析。
请注意,一旦模式包含异步转换,该模式上的所有解析操作都必须是异步的,即使在同步上下文中也是如此。
来源:src/__tests__/transformer.test.ts114-123 src/__tests__/transformer.test.ts124-134
如果基础模式验证失败,转换会短路
如果输入数据未能通过基础模式验证,则转换函数永远不会执行,并返回原始验证错误。
来源:src/__tests__/transformer.test.ts199-234
精炼和转换都使用 ZodEffects 实现,但它们服务于不同的目的
| 功能 | 细化 | 转换 |
|---|---|---|
| 目的 | 验证数据而不改变其类型 | 将数据从一种类型转换为另一种类型 |
| 输出类型 | 与输入类型相同 | 可以与输入类型不同 |
| 类型推断 | 保留或收窄类型 | 根据 transform 函数改变类型 |
| 实现 | 使用 ZodEffects,类型为“refinement” | 使用 ZodEffects,类型为“transform” |
精炼和转换可以结合使用,通常在验证链中,精炼在转换之前应用。
虽然这并非严格意义上的转换,但 Zod 提供了一个 .default() 方法,允许您为模式指定默认值
您也可以使用函数来动态生成默认值
来源:src/__tests__/transformer.test.ts136-139 src/__tests__/transformer.test.ts141-147 src/__tests__/transformer.test.ts149-158
Zod 中的转换提供了一种强大的方式,可以在验证过程中修改数据,同时保持完整的类型安全。它们允许您
通过将转换与其他 Zod 功能结合使用,您可以构建既类型安全又经过运行时验证的复杂数据处理管道。