ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zod:支持 TypeScript 的验证库,具备静态类型推断,验证速度最高可提升 9 倍!

Zod:支持 TypeScript 的验证库,具备静态类型推断,验证速度最高可提升 9 倍! 什么是 ZodZod 是一个优先支持 TypeScript 的验证库。能定义一个模式用它来解析数据最终得到经过强类型验证的结果。import * as z from zod; const User z.object({ name: z.string(), }); // 一些不可信的数据 const input { /* 数据内容 */ }; // 解析结果经过验证且类型安全 const data User.parse(input); // 可以放心使用它 :) console.log(data.name);特性零外部依赖不依赖其他外部库减少项目的复杂度和潜在风险。跨环境兼容可在 Node.js 和所有现代浏览器中使用具有广泛的适用性。轻量级核心包仅 2kbgzipped对项目体积影响极小。不可变 API方法返回新实例避免副作用保证数据的安全性和可维护性。简洁接口提供简洁易用的 API降低开发难度。多语言支持可与 TypeScript 和纯 JavaScript 配合使用满足不同开发需求。内置 JSON Schema 转换方便与其他系统进行交互和数据验证。丰富的生态系统有众多插件和工具可供使用扩展功能强大。安装npm install zod基本用法使用之前需要先定义一个模式。在本指南中使用一个简单的对象模式。import * as z from zod; const Player z.object({ username: z.string(), xp: z.number(), });解析数据对于任何 Zod 模式可使用 .parse 方法来验证输入。若输入有效Zod 将返回一个经过强类型处理的输入数据的深拷贝。Player.parse({ username: billie, xp: 100 }); // 返回 { username: billie, xp: 100 }注意若模式使用了某些异步 API如异步细化async refinements或转换transforms则需使用 .parseAsync() 方法。const schema z.string().refine(async (val) val.length 8); await schema.parseAsync(hello); // helloAOT 编译对于频繁进行验证的场景z.compile(schema) 会返回一个经过提前编译的模式克隆以加快验证速度。有效输入将使用编译后的路径无效输入则回退到常规解析器确保错误报告保持一致。在 55 个模式的基准测试中平均提速 2.4 倍并且提速效果会随着模式每次解析的工作量增加而提升大型对象数组约 9 倍20 个键的对象约 9 倍嵌套对象约 4.5 倍而单纯的 z.string() 则没有提速效果因为编译主要是消除了每个节点的调度和分配而单个 typeof 操作本身就不存在这些开销。const CompiledPlayer z.compile(Player); CompiledPlayer.parse({ username: billie, xp: 100 });若要在导入后全局启用模式编译可添加以下代码import zod/compile; // 需在定义模式的模块之前导入注意事项编译使用了 new Function。当设置 z.config({ jitless: true }) 时如在 CSP 环境中全局模式将自动禁用直接调用 z.compile() 则是显式启用。带有异步细化或转换的模式无法编译还有一些其他构造也不支持。这不是错误z.compile() 会原样返回模式并继续使用常规解析器就像全局模式未启用一样。若要抛出错误提示可传递 { strict: true }此时会抛出 ZodCompileAsyncError 或 ZodCompileUnsupportedError。对于无效输入细化和转换操作可能会运行两次先快速路径再回退。从编译后的模式派生新的模式如 .refine()、.extend() 等会返回未编译的模式需要对最终模式进行编译。详细信息可查看编译文档。错误处理当验证失败时.parse() 方法会抛出一个 ZodError 实例其中包含详细的验证问题信息。try { Player.parse({ username: 42, xp: 100 }); } catch (err) { if (err instanceof z.ZodError) { err.issues; /* [ { expected: string, code: invalid_type, path: [ username ], message: Invalid input: expected string }, { expected: number, code: invalid_type, path: [ xp ], message: Invalid input: expected number } ] */ } }为避免使用 try/catch 块可使用 .safeParse() 方法它会返回一个普通的结果对象其中包含成功解析的数据或 ZodError。结果类型是一个可区分的联合类型方便处理两种情况。const result Player.safeParse({ username: 42, xp: 100 }); if (!result.success) { result.error; // ZodError 实例 } else { result.data; // { username: string; xp: number } }注意若模式使用了某些异步 API如异步细化或转换则需使用 .safeParseAsync() 方法。const schema z.string().refine(async (val) val.length 8); await schema.safeParseAsync(hello); // { success: true; data: hello }类型推断Zod 可以从模式定义中推断出静态类型。可使用 z.infer 工具提取该类型并在代码中随意使用。const Player z.object({ username: z.string(), xp: z.number(), }); // 提取推断出的类型 type Player z.infer; // 在代码中使用 const player: Player { username: billie, xp: 100 };在某些情况下模式的输入和输出类型可能会不同。例如.transform() API 可以将输入从一种类型转换为另一种类型。在这种情况下可以分别提取输入和输出类型const mySchema z.string().transform((val) val.length); type MySchemaIn z.input; // string type MySchemaOut z.output; // 等同于 z.infer // number
返回列表