关于 zod
Zod 是面向 TypeScript 的 schema 校验库,让开发者从同一 schema 获得运行时校验和静态类型推断。它支持解析、细化、转换及组合式 schema 定义,且无需外部依赖。
主要功能
- 01运行时校验与 TypeScript 类型推断
- 02组合对象、数组、元组和联合 schema
- 03细化规则与数据转换
- 04同步和异步解析
- 05详细的校验错误信息
适用场景
- 01在应用边界校验 API 数据
- 02检查环境变量和不可信输入
- 03定义带类型推断的表单 schema
- 04转换并校验解析后的数据
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ enderpuentes/ ai-agent-skills --skill zod安装后在 Claude Code 中输入/zod确认已加载。
附带文件LICENSE.mdreference.md
详细介绍
Zod
概述
Zod 是一个以 TypeScript 为先的模式验证库,支持静态类型推断。只需定义一次模式,即可同时获得运行时验证和 TypeScript 类型(通过 z.infer)。零外部依赖;可在 Node 和浏览器中运行。适用于表单(例如与 react-hook-form 配合使用)、API 解析、环境变量以及任何不可信输入。
要求:建议使用 TypeScript 5.5+;在 tsconfig.json 中启用 strict。
安装:通过包管理器添加 zod。参阅 zod.dev。
快速开始
import { z } from "zod";
const User = z.object({
name: z.string(),
age: z.number().optional(),
});
type User = z.infer<typeof User>;
// { name: string; age?: number }
const data = User.parse(input); // throws ZodError if invalid
const result = User.safeParse(input); // { success: true, data } | { success: false, error }
基本类型与常用类型
| 模式 | 类型 | 说明 |
|---|---|---|
z.string() | string | |
z.number() | number | |
z.boolean() | boolean | |
z.bigint() | bigint | |
z.date() | Date | |
z.undefined() | undefined | |
z.null() | null | |
z.void() | void | |
z.any() | any | |
z.unknown() | unknown | |
z.never() | never | |
z.literal("x") | literal | |
z.enum(["a", "b"]) | 字面量联合类型 | |
z.string().email() | string | 电子邮件格式 |
z.string().url() | string | URL |
z.string().uuid() | string | UUID |
z.string().datetime() | string | ISO 日期时间 |
z.number().int() | number | 整数 |
z.number().min(n).max(m) | number | 范围 |
z.boolean() / z.string().transform(...) | stringbool | 将 "true"/"false" 强制转换为布尔值 |
可选:.optional() → T | undefined。可空:.nullable() → T | null。可空且可选:.nullish() → T | null | undefined。默认值:.default(value)。
对象
const Schema = z.object({
name: z.string(),
age: z.number().optional(),
tags: z.array(z.string()).default([]),
});
type Schema = z.infer<typeof Schema>;
- .shape:
Schema.shape.name(访问字段模式)。 - .keyof():
Schema.keyof()→ 键的枚举。 - .extend({ ... }):添加或覆盖键。
- .pick({ name }) / .omit({ age }):选取或省略部分键。
- .partial() / .required({ name }):将字段设为可选或必填。
- .strict():不允许额外键(
z.object的默认行为)。z.strictObject / z.looseObject 提供其他行为变体。 - .catchall(z.string()):允许额外键,并为其指定模式。
- 嵌套:
z.object({ user: z.object({ name: z.string() }) })。 - 递归:使用
z.lazy(() => Category)定义自引用结构。
数组与元组
- 数组:
z.array(z.string())、z.string().array()。 - 元组:
z.tuple([z.string(), z.number()])— 长度和类型固定。 - 非空:使用
.min(1),或在可用时使用专用辅助方法。
联合与交叉
- 联合:
z.union([z.string(), z.number()])或z.string().or(z.number())。 - 判别联合:使用一个公共键(例如
type: "a"),并搭配z.discriminatedUnion("type", [z.object({ type: z.literal("a"), ... }), ...])。 - 交叉:
z.intersection(A, B)或A.and(B)。
细化与转换
- .refine(fn, message?):自定义验证;保持类型不变。
- .superRefine:添加多个问题,或执行异步验证;将问题推入
ctx。 - .transform(fn):更改输出类型。输入和输出类型可以不同;使用
z.input<typeof schema>和z.output<typeof schema>(或使用z.infer获取输出类型)。 - .pipe(otherSchema):串联验证或转换(例如通过
z.string().pipe(z.coerce.number())将字符串转换为数字)。
解析与错误
- .parse(input):返回数据,或抛出 ZodError。
- .safeParse(input):返回
{ success: true, data }或{ success: false, error: ZodError }。 - ZodError:
error.issues(由{ path, message, code }组成的数组);使用error.format()获取嵌套结构。 - 异步:对于包含异步细化或转换的模式,使用
.parseAsync/.safeParseAsync。
类型推断
- z.infer:输出类型(经过转换或默认值处理后)。
- z.input:输入类型(转换前;适用于输入类型与输出类型不同时)。
- z.output:与输出类型的
z.infer相同。
const S = z.string().transform((s) => s.length);
type In = z.input<typeof S>; // string
type Out = z.output<typeof S>; // number
集成:React Hook Form
使用 @hookform/resolvers 和 zodResolver:
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormValues = z.infer<typeof formSchema>;
const form = useForm<FormValues>({
resolver: zodResolver(formSchema),
defaultValues: { email: "", password: "" },
});
最佳实践
- 在 API 边界处优先使用严格模式的 schema(不允许额外键);仅在需要转发未知键时使用 .passthrough()。
- 对具有默认值的可选字段使用 .default()。
- 解析 API/env 时,使用 safeParse 并处理错误;根据
error.issues显示对用户友好的消息。 - 对变体载荷使用判别联合(例如,根据
type区分事件)。 - 仅在安全时进行强制转换:
z.coerce.number()、z.coerce.boolean()或自定义.transform()。
常见错误
- 忘记启用严格模式:保持 TypeScript
strict: true;Zod 在严格模式下效果最佳。 - 输入与输出:使用
.transform()后,如果调用方看到的类型不同,请使用z.input<>/z.output<>。 - 在热点路径中调用 parse:优先在边界处(例如 API 处理程序、表单提交时)验证一次,而不是每次渲染时都验证。
- schema 过于宽泛:当领域规则有要求时,优先使用具体类型(例如
.email()、.min()),而不是普通的z.string()。
更多资源
- reference.md — Zod 官方文档链接、API 章节(原始类型、对象、字符串、数字、细化等)、Zod Mini、生态系统。
- 官方文档:https://zod.dev — 简介、API、基础知识、生态系统。
- API(Zod 4):https://zod.dev/api — 完整的 schema 类型和方法。
- 大模型 / 索引:https://zod.dev/llms.txt — 面向工具/Agent 的结构化文档。
评论
支持 Markdown