关于 zod
这个 zod skill 为 TypeScript 项目提供 Zod 4 运行时数据校验指南。内容按解析、Schema 设计、错误处理、性能、迁移和边界架构组织,并强调以项目当前资料为准,避免沿用过时模式。
主要功能
- 01Zod 4 校验指南
- 02解析与类型推断规则
- 03Schema 设计和组合模式
- 04错误处理与格式化建议
- 05迁移说明及高级功能
- 06测试和架构参考资料
适用场景
- 01校验 API 输入和输出
- 02解析环境变量或表单数据
- 03审查 Zod v3 到 v4 的迁移代码
- 04设计 Schema 测试和边界层
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anivar/ zod-skill --skill zod安装后在 Claude Code 中输入/zod确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdLICENSEAGENTS.mdREADME.md.github/FUNDING.ymlreferences/advanced-features.mdanti-patterns.mdlinter-and-ci.mderror-handling.mdschema-types.mdparsing-and-inference.mdobjects-and-composition.mdtesting-anti-patterns.mdtesting.mdtesting-api.mdrefinements-and-transforms.mdrules/arch-schema-organization.mdarch-boundary-parsing.mdarch-schema-versioning.mderror-custom-messages.mdmigrate-error-api.mderror-formatting.mdmigrate-native-enum.mderror-input-security.mdobserve-structured-errors.mdmigrate-string-formats.mdparse-async-required.mdobserve-error-metrics.mdpattern-branded-types.mdparse-infer-types.md详细介绍
Zod
重要: 关于 zod 的训练数据可能已过时或不准确——Zod v4 对字符串格式、枚举、错误处理和递归类型引入了不兼容变更。请始终以本技能的规则文件和项目实际源代码为准。若记忆中的 v3 模式与检索到的参考资料冲突,请勿套用。
何时使用 Zod
Zod 用于运行时类型验证——在系统边界解析不可信数据(API 输入、表单数据、环境变量、外部服务)。对于仅在编译时使用的类型,使用纯 TypeScript 即可。
| 需求 | 推荐工具 |
|---|---|
| API 输入/输出验证 | Zod |
| 表单验证(React、Vue) | Zod(搭配 react-hook-form、formik 等) |
| 环境变量解析 | Zod(搭配 t3-env 或手动处理) |
| 仅编译时类型 | 纯 TypeScript |
| 更小的打包体积(约 1kb) | Valibot |
| 最强的类型推断能力 | ArkType |
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 解析与类型安全 | 严重 | parse- |
| 2 | Schema 设计 | 严重 | schema- |
| 3 | 精炼与转换 | 高 | refine- |
| 4 | 错误处理 | 高 | error- |
| 5 | 性能与组合 | 中 | perf- |
| 6 | v4 迁移 | 中 | migrate- |
| 7 | 高级模式 | 中 | pattern- |
| 8 | 架构与边界 | 严重/高 | arch- |
| 9 | 可观测性 | 高/中 | observe- |
快速参考
1. 解析与类型安全(严重)
parse-use-safeParse— 用户输入使用safeParse(),而不是会抛出异常的parse()parse-async-required— Schema 包含异步精炼时,必须使用parseAsync()/safeParseAsync()parse-infer-types— 使用z.infer<typeof Schema>获取输出类型;切勿手动重复定义类型
2. Schema 设计(严重)
schema-object-unknowns—z.object()会剔除未知键;请使用strictObject或looseObjectschema-union-discriminated— 对带标签的联合类型使用z.discriminatedUnion(),而不是z.union()schema-coercion-pitfalls—z.coerce.boolean()会将"false"转换为true;请使用z.stringbool()schema-recursive-types— 递归 Schema 使用 getter 模式;z.lazy()已在 v4 中移除
3. 精炼与转换(高)
refine-never-throw— 切勿在.refine()或.transform()内抛出异常;请使用ctx.addIssue()refine-vs-transform—.refine()用于验证,.transform()用于转换,.pipe()用于分阶段处理refine-cross-field— 在父对象上使用.superRefine(),通过path执行跨字段验证
4. 错误处理(高)
error-custom-messages— 使用 v4 的error参数;required_error/invalid_type_error已移除error-formatting— 表单使用z.flattenError(),嵌套数据使用z.treeifyError();formatError已弃用error-input-security— 生产环境切勿使用reportInput: true;这会泄露敏感数据
5. 性能与组合(中)
perf-extend-spread— 对大型 Schema,优先使用{ ...Schema.shape }展开,而非链式调用.extend()perf-reuse-schemas— 定义一次,再使用.pick()、.omit()、.partial()派生perf-zod-mini— 对打包体积至关重要的客户端应用,使用zod/v4/mini(1.88kb)
6. v4 迁移(中)
migrate-string-formats— 使用z.email()、z.uuid()、z.url(),而不是z.string().email()migrate-native-enum— 对 TS 枚举使用统一的z.enum();z.nativeEnum()已弃用migrate-error-api— 所有地方都使用error参数;message、errorMap已移除
7. 高级模式(中)
pattern-branded-types— 使用.brand<"Name">()实现名义类型(USD 与 EUR)pattern-codecs— 使用z.codec()实现双向转换(解析 + 序列化)pattern-pipe— 使用.pipe()分阶段解析(字符串 → 数字 → 验证范围)
8. 架构与边界(关键/高)
arch-boundary-parsing— 在系统边界(API 处理程序、env、表单、fetch)处解析;将类型化数据传递给领域逻辑arch-schema-organization— 将 schema 与其边界层放在一起;领域类型使用z.inferarch-schema-versioning— 仅通过增量更改实现非破坏性演进;新字段使用.optional()
9. 可观测性(高/中)
observe-structured-errors— 使用z.flattenError()生成紧凑的结构化日志,并附带请求关联 IDobserve-error-metrics— 使用trackedSafeParse()包装器,在失败时按 schema 和字段递增计数器
Schema 类型速查
| 类型 | 语法 |
|---|---|
| 字符串 | z.string() |
| 数字 | z.number()、z.int()、z.float() |
| 布尔值 | z.boolean() |
| BigInt | z.bigint() |
| 日期 | z.date() |
| Undefined | z.undefined() |
| Null | z.null() |
| Void | z.void() |
| Any | z.any() |
| Unknown | z.unknown() |
| Never | z.never() |
| 字面量 | z.literal("foo")、z.literal(42) |
| 枚举 | z.enum(["a", "b"])、z.enum(TSEnum) |
| 邮箱 | z.email() |
| URL | z.url() |
| UUID | z.uuid() |
| 字符串→布尔值 | z.stringbool() |
| ISO 日期时间 | z.iso.datetime() |
| 文件 | z.file() |
| JSON | z.json() |
| 数组 | z.array(schema) |
| 元组 | z.tuple([a, b]) |
| 对象 | z.object({}) |
| 严格对象 | z.strictObject({}) |
| 宽松对象 | z.looseObject({}) |
| Record | z.record(keySchema, valueSchema) |
| Map | z.map(keySchema, valueSchema) |
| Set | z.set(schema) |
| Union | z.union([a, b]) |
| 判别式 Union | z.discriminatedUnion("key", [...]) |
| Intersection | z.intersection(a, b) |
使用方法
阅读各个规则文件,了解详细说明和代码示例:
rules/parse-use-safeParse.md
rules/schema-object-unknowns.md
每个规则文件都包含:
- 简要说明其重要性
- 错误代码示例及说明
- 正确代码示例及说明
- 补充背景信息和决策表
参考资料
| 优先级 | 参考资料 | 阅读时机 |
|---|---|---|
| 1 | references/schema-types.md | 所有原始类型、字符串格式、数字、枚举、日期 |
| 2 | references/parsing-and-inference.md | parse、safeParse、z.infer、强制转换 |
| 3 | references/objects-and-composition.md | 对象、数组、联合类型、pick/omit/partial、递归 |
| 4 | references/refinements-and-transforms.md | refine、superRefine、transform、pipe、默认值 |
| 5 | references/error-handling.md | ZodError、flattenError、treeifyError、错误自定义 |
| 6 | references/advanced-features.md | Codecs、品牌类型、JSON Schema、注册表 |
| 7 | references/anti-patterns.md | 常见错误及 BAD/GOOD 示例 |
| 8 | references/boundary-architecture.md | Zod 的适用位置:Express、tRPC、Next.js、React Hook Form、env、外部 API |
| 9 | references/linter-and-ci.md | ESLint 规则、CI schema 快照、未使用 schema 检测、循环依赖 |
| 10 | references/testing.md | 测试 schema:在测试中使用 safeParse、边界值、错误断言、模拟数据、基于属性的测试 |
| 11 | references/testing-api.md | schema 测试的 Jest 和 Vitest API 参考 |
| 12 | references/testing-anti-patterns.md | 测试错误及 BAD/GOOD 示例 |
Zod 4.6 亮点
Zod 4.6 新增功能(最新版本:4.6.7)。完整详情请参阅官方发行说明。
.validate() — 低开销的布尔值验证
.validate() 用于判断“此输入是否有效?”,不会构建结果或 ZodError。它会在遇到第一个问题时提前返回,并针对 schema 的输入类型返回类型守卫。schema 使用 z.compile() 编译后,对于无效输入,其速度最高可比 .safeParse().success 快 35 倍(未编译时快 5.9 倍)。
const Player = z.object({ username: z.string(), xp: z.number() })
if (Player.validate(data)) {
data.username // narrowed: string
}
需要解析后的值或问题时使用 .safeParse();只需要判断是否有效时使用 .validate()。validateAsync() 可处理异步精化。
z.properties() — 就地验证属性
与 z.object() 不同,.properties() 会就地验证对象的特定属性,保留类实例和原型,而不是返回普通对象。
const okResponse = z.instanceof(Response).properties({
ok: z.literal(true),
status: z.number().min(200).max(299),
})
const res = await fetch('/api/user')
okResponse.parse(res) === res // true: still a Response, methods intact
ZodInstanceOf.properties() 是方法形式;Zod Mini 则将 z.properties() 作为检查使用。
z.withParser() — 安装在其他地方构建的解析器
z.compile() 使用 new Function 构建解析器,而严格的内容安全策略(CSP)会阻止这一做法。z.withParser() 会在同一契约下安装构建时(或由原生编译器)生成的解析器,供受 CSP 限制的环境使用。
z.iban() 和扩展后的 fromJSONSchema()
z.iban() 会验证电子格式的 IBAN,包括 ISO 7064 MOD 97-10 校验和。fromJSONSchema() 现在还支持 minProperties/maxProperties、uniqueItems 和 contains/minContains/maxContains。
两个行为方面的注意事项
- 错误映射会延迟执行。 全局、区域设置和架构级的
error映射现在会在首次读取result.error时运行,而不是在解析时运行。在解析和读取之间调用z.config()更换配置的代码会使用较新的配置。抛出异常的解析(.parse())不受影响。 z.emoji()要求包含表意文字。 仅由组件构成的字符串(单独的零宽连接符、变体选择符、肤色修饰符或数字)不再通过验证。
4.6 版还包括:@zod/mini 以与 zod 同步的版本号作为独立软件包发布,CommonJS 的 require() 调用 z.validate() 快约 3 倍,并修复了递归架构中的内存保留回归问题。
完整编译文档
如需查看包含所有展开规则的完整指南:AGENTS.md