Zod zod

Zod 是一个 TypeScript 优先的架构验证库,用于在运行时验证数据并自动推断静态类型。它支持定义类型安全架构,进行数据转换,生成 JSON Schema,并处理错误,适用于 API 验证、表单数据、环境变量等场景。关键词:Zod, TypeScript, 验证, 架构, 类型安全, 运行时验证, 错误处理, JSON Schema, 数据转换。

前端开发 0 次安装 0 次浏览 更新于 3/7/2026

name: zod description: TypeScript 优先的架构验证和类型推断。用于验证 API 请求/响应、表单数据、环境变量、配置,定义具有运行时验证的类型安全架构,转换数据,为 OpenAPI/AI 生成 JSON Schema,或处理缺失验证错误、类型推断问题、验证错误处理问题。零依赖(2kb 压缩后)。 license: MIT metadata: version: 2.0.0 last_verified: 2025-11-17 package_version: 4.1.12+ keywords: - zod - 验证 - 架构 - typescript - 类型安全 - 运行时验证 - 类型推断 - 数据验证 - 表单验证 - api 验证 - json-schema - 优化 - 转换 - 错误处理 - 解析 - 安全解析 - z.object - z.string - z.number - z.array - z.union - z.discriminatedUnion - z.refine - z.transform - z.infer - z.coerce - z.enum - z.literal - z.tuple - z.record - z.intersection - z.codec - z.toJSONSchema - z.treeifyError - z.flattenError - z.prettifyError - z.registry - z.globalRegistry - .register - .meta - 错误定制 - 本地化 - i18n - 迁移 - v3 到 v4 - 破坏性更改 - tRPC - prisma-zod - react-hook-form - trpc - 环境变量 - 环境验证 - 配置验证 - dto - 类型守卫 - 运行时类型检查 token_savings: 65% errors_prevented: 8 production_tested: true related_skills: - react-hook-form-zod - typescript-mcp

Zod: TypeScript 优先的架构验证

概述

Zod 是一个 TypeScript 优先的验证库,使开发者能够在运行时定义架构以验证数据,同时自动推断静态 TypeScript 类型。具有零依赖和 2kb 核心包(压缩后),Zod 提供不可变的、可组合的验证和全面的错误处理。

安装

bun add zod
# 或
bun add zod
# 或
bun add zod
# 或
yarn add zod

要求:

  • TypeScript v5.5+,在 tsconfig.json 中设置 "strict": true
  • Zod 4.x (4.1.12+)

重要提示: 本技能文档涵盖 Zod 4.x 功能。以下 API 需要 Zod 4,在 Zod 3.x 中不可用:

  • z.codec() - 双向转换
  • z.iso.date(), z.iso.time(), z.iso.datetime(), z.iso.duration() - ISO 格式验证器
  • z.toJSONSchema() - JSON Schema 生成
  • z.treeifyError(), z.prettifyError(), z.flattenError() - 新的错误格式化助手
  • .meta() - 增强的元数据(Zod 3.x 仅支持 .describe()
  • 统一的 error 参数 - 替换 message, invalid_type_error, required_error, errorMap

有关 Zod 3.x 兼容性或迁移指导,请参见 https://zod.dev

从 Zod v3 迁移到 v4

加载 references/migration-guide.md 获取完整的 v3 到 v4 迁移文档。

快速总结

Zod v4 引入了破坏性更改以提高性能:

  • 错误定制: 使用统一的 error 参数(替换 message, invalid_type_error, required_error
  • 数字验证: 更严格 - 拒绝 Infinity 和不安全整数
  • 字符串格式: 现在为顶级函数(z.email() 而不是 z.string().email()
  • 对象默认值: 即使在可选字段中也应用
  • 废弃的 API: 使用 .extend()(而不是 .merge()), z.treeifyError()(而不是 error.format()
  • 函数验证: 使用 .implement() 方法
  • UUID 验证: 更严格的 RFC 9562/4122 合规性

→ 加载 references/migration-guide.md 获取: 完整的破坏性更改、迁移清单、渐进迁移策略、回滚说明

核心概念

基本使用模式

import { z } from "zod";

// 定义架构
const UserSchema = z.object({
  username: z.string(),
  age: z.number().int().positive(),
  email: z.string().email(),
});

// 推断 TypeScript 类型
type User = z.infer<typeof UserSchema>;

// 验证数据(错误时抛出)
const user = UserSchema.parse(data);

// 验证数据(返回结果对象)
const result = UserSchema.safeParse(data);
if (result.success) {
  console.log(result.data); // 类型化!
} else {
  console.error(result.error); // ZodError
}

解析方法

根据错误处理需求使用适当的解析方法:

  • .parse(data) - 无效输入时抛出 ZodError;成功时返回强类型数据
  • .safeParse(data) - 返回 { success: true, data }{ success: false, error }(无异常)
  • .parseAsync(data) - 用于具有异步优化/转换的架构
  • .safeParseAsync(data) - 不抛出的异步版本

最佳实践: 使用 .safeParse() 避免 try-catch 块,并利用 discriminated union。

原始类型

字符串

z.string()                    // 基本字符串
z.string().min(5)            // 最小长度
z.string().max(100)          // 最大长度
z.string().length(10)        // 精确长度
z.string().email()           // 电子邮件验证
z.string().url()             // URL 验证
z.string().uuid()            // UUID 格式
z.string().regex(/^\d+$/)    // 自定义模式
z.string().startsWith("pre") // 前缀检查
z.string().endsWith("suf")   // 后缀检查
z.string().trim()            // 自动修剪空白
z.string().toLowerCase()     // 自动小写
z.string().toUpperCase()     // 自动大写

// ISO 格式(Zod 4+)
z.iso.date()                 // YYYY-MM-DD
z.iso.time()                 // HH:MM:SS
z.iso.datetime()             // ISO 8601 日期时间
z.iso.duration()             // ISO 8601 时长

// 网络格式
z.ipv4()                     // IPv4 地址
z.ipv6()                     // IPv6 地址
z.cidrv4()                   // IPv4 CIDR 表示法
z.cidrv6()                   // IPv6 CIDR 表示法

// 其他格式
z.jwt()                      // JWT 令牌
z.nanoid()                   // Nanoid
z.cuid()                     // CUID
z.cuid2()                    // CUID2
z.ulid()                     // ULID
z.base64()                   // Base64 编码
z.hex()                      // 十六进制

数字

z.number()                   // 基本数字
z.number().int()             // 仅整数
z.number().positive()        // > 0
z.number().nonnegative()     // >= 0
z.number().negative()        // < 0
z.number().nonpositive()     // <= 0
z.number().min(0)            // 最小值
z.number().max(100)          // 最大值
z.number().gt(0)             // 大于
z.number().gte(0)            // 大于或等于
z.number().lt(100)           // 小于
z.number().lte(100)          // 小于或等于
z.number().multipleOf(5)     // 必须是 5 的倍数
z.int()                      // z.number().int() 的简写
z.int32()                    // 32 位整数
z.nan()                      // NaN 值

强制转换(类型转换)

z.coerce.string()            // 转换为字符串
z.coerce.number()            // 转换为数字
z.coerce.boolean()           // 转换为布尔值
z.coerce.bigint()            // 转换为 bigint
z.coerce.date()              // 转换为 Date

// 示例:解析查询参数
const QuerySchema = z.object({
  page: z.coerce.number().int().positive(),
  limit: z.coerce.number().int().max(100).default(10),
});

// "?page=5&limit=20" -> { page: 5, limit: 20 }

其他原始类型

z.boolean()                  // 布尔值
z.date()                     // Date 对象
z.date().min(new Date("2020-01-01"))
z.date().max(new Date("2030-12-31"))
z.bigint()                   // BigInt
z.symbol()                   // Symbol
z.null()                     // Null
z.undefined()                // Undefined
z.void()                     // Void(undefined)

复杂类型

对象

const PersonSchema = z.object({
  name: z.string(),
  age: z.number(),
  address: z.object({
    street: z.string(),
    city: z.string(),
    country: z.string(),
  }),
});

type Person = z.infer<typeof PersonSchema>;

// 对象方法
PersonSchema.shape                 // 访问形状
PersonSchema.keyof()              // 获取键的联合
PersonSchema.extend({ role: z.string() })  // 添加字段
PersonSchema.pick({ name: true }) // 选择特定字段
PersonSchema.omit({ age: true })  // 省略字段
PersonSchema.partial()            // 使所有字段可选
PersonSchema.required()           // 使所有字段必需
PersonSchema.deepPartial()        // 递归可选

// 严格与松散对象
z.strictObject({ ... })           // 不允许额外键(抛出)
z.object({ ... })                 // 去除额外键(默认)
z.looseObject({ ... })            // 允许额外键

数组

z.array(z.string())              // 字符串数组
z.array(z.number()).min(1)       // 至少 1 个元素
z.array(z.number()).max(10)      // 最多 10 个元素
z.array(z.number()).length(5)    // 精确 5 个元素
z.array(z.number()).nonempty()   // 至少 1 个元素

// 嵌套数组
z.array(z.array(z.number()))     // number[][]

元组

z.tuple([z.string(), z.number()]) // [string, number]
z.tuple([z.string(), z.number()]).rest(z.boolean()) // [string, number, ...boolean[]]

枚举和字面量

// 枚举
const RoleEnum = z.enum(["admin", "user", "guest"]);
type Role = z.infer<typeof RoleEnum>; // "admin" | "user" | "guest"

// 字面量值
z.literal("exact_value")
z.literal(42)
z.literal(true)

// 原生 TypeScript 枚举
enum Fruits {
  Apple,
  Banana,
}
z.nativeEnum(Fruits)

// 枚举方法
RoleEnum.enum.admin              // "admin"
RoleEnum.exclude(["guest"])      // 排除值
RoleEnum.extract(["admin", "user"]) // 仅包含

联合类型

// 基本联合
z.union([z.string(), z.number()])

// 鉴别联合(更好的性能和类型推断)
const ResponseSchema = z.discriminatedUnion("status", [
  z.object({ status: z.literal("success"), data: z.any() }),
  z.object({ status: z.literal("error"), message: z.string() }),
]);

type Response = z.infer<typeof ResponseSchema>;
// { status: "success", data: any } | { status: "error", message: string }

交集类型

const BaseSchema = z.object({ id: z.string() });
const ExtendedSchema = z.object({ name: z.string() });

const Combined = z.intersection(BaseSchema, ExtendedSchema);
// 等价于:z.object({ id: z.string(), name: z.string() })

记录和映射

// 记录:具有类型化键和值的对象
z.record(z.string())             // { [key: string]: string }
z.record(z.string(), z.number()) // { [key: string]: number }

// 部分记录(某些键可选)
z.partialRecord(z.enum(["a", "b"]), z.string())

// 映射
z.map(z.string(), z.number())    // Map<string, number>
z.set(z.string())                // Set<string>

高级模式

加载 references/advanced-patterns.md 获取完整的高级验证和转换模式。

快速参考

优化(自定义验证):

z.string().refine((val) => val.length >= 8, "太短");
z.object({ password, confirmPassword }).superRefine((data, ctx) => { /* ... */ });

转换(修改数据):

z.string().transform((val) => val.trim());
z.string().pipe(z.coerce.number());

编解码器(双向转换 - v4.1 新功能):

const DateCodec = z.codec(
  z.iso.datetime(),
  z.date(),
  {
    decode: (str) => new Date(str),
    encode: (date) => date.toISOString(),
  }
);

递归类型:

const CategorySchema: z.ZodType<Category> = z.lazy(() =>
  z.object({ name: z.string(), subcategories: z.array(CategorySchema) })
);

可选/可为空:

z.string().optional()            // string | undefined
z.string().nullable()            // string | null
z.string().default("default")    // 如果未定义则提供默认值

只读和品牌:

z.object({ ... }).readonly()     // 只读属性
z.string().brand<"UserId">()     // 名义类型

→ 加载 references/advanced-patterns.md 获取: 完整的优化模式、异步验证、编解码器示例、可组合架构、条件验证、性能优化

错误处理

加载 references/error-handling.md 获取完整的错误格式化和定制指南。

快速参考

错误格式化方法:

// 用于表单
const { fieldErrors } = z.flattenError(error);

// 用于嵌套数据
const tree = z.treeifyError(error);
const nameError = tree.properties?.user?.properties?.name?.errors?.[0];

// 用于调试
console.log(z.prettifyError(error));

自定义错误消息(三级):

// 1. 架构级别(最高优先级)
z.string({ error: "自定义消息" });
z.string().min(5, "太短");

// 2. 每解析级别
schema.parse(data, { error: (issue) => ({ message: "..." }) });

// 3. 全局级别
z.config({ customError: (issue) => ({ message: "..." }) });

本地化(40+ 语言):

z.config(z.locales.es());  // 西班牙语
z.config(z.locales.fr());  // 法语

→ 加载 references/error-handling.md 获取: 完整的错误格式化示例、自定义错误模式、本地化设置、错误代码参考

类型推断

加载 references/type-inference.md 获取完整的类型推断和元数据文档。

快速参考

基本类型推断:

const UserSchema = z.object({ name: z.string() });
type User = z.infer<typeof UserSchema>; // { name: string }

输入与输出(用于转换):

const TransformSchema = z.string().transform((s) => s.length);
type Input = z.input<typeof TransformSchema>;   // string
type Output = z.output<typeof TransformSchema>; // number

JSON Schema 转换:

const jsonSchema = z.toJSONSchema(UserSchema, {
  target: "openapi-3.0",
  metadata: true,
});

元数据:

// 添加元数据
const EmailSchema = z.string().email().meta({
  title: "电子邮件地址",
  description: "用户的电子邮件地址",
});

// 创建自定义注册表
const formRegistry = z.registry<FormFieldMeta>();

→ 加载 references/type-inference.md 获取: 完整的类型推断模式、JSON Schema 选项、元数据系统、自定义注册表、品牌类型

函数

验证函数输入和输出:

const AddFunction = z.function()
  .args(z.number(), z.number())  // 参数
  .returns(z.number());           // 返回类型

// 实现类型化函数
const add = AddFunction.implement((a, b) => {
  return a + b; // 类型检查!
});

// 异步函数
const FetchFunction = z.function()
  .args(z.string())
  .returns(z.promise(z.object({ data: z.any() })))
  .implementAsync(async (url) => {
    const response = await fetch(url);
    return response.json();
  });

常见模式

环境变量

const EnvSchema = z.object({
  NODE_ENV: z.enum(["development", "production", "test"]),
  DATABASE_URL: z.string().url(),
  PORT: z.coerce.number().int().positive().default(3000),
  API_KEY: z.string().min(32),
});

// 在启动时验证
const env = EnvSchema.parse(process.env);

// 现在使用类型化环境
console.log(env.PORT); // number

API 请求验证

const CreateUserRequest = z.object({
  username: z.string().min(3).max(20),
  email: z.string().email(),
  password: z.string().min(8),
  age: z.number().int().positive().optional(),
});

// Express 示例
app.post("/users", async (req, res) => {
  const result = CreateUserRequest.safeParse(req.body);

  if (!result.success) {
    return res.status(400).json({
      errors: z.flattenError(result.error).fieldErrors,
    });
  }

  const user = await createUser(result.data);
  res.json(user);
});

表单验证

const FormSchema = z.object({
  firstName: z.string().min(1, "姓氏必需"),
  lastName: z.string().min(1, "名字必需"),
  email: z.string().email("无效电子邮件"),
  age: z.coerce.number().int().min(18, "必须 18 岁以上"),
  agreeToTerms: z.literal(true, {
    errorMap: () => ({ message: "必须接受条款" }),
  }),
});

type FormData = z.infer<typeof FormSchema>;

部分更新

const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
});

// 用于 PATCH 请求:使除 id 外的所有内容可选
const UpdateUserSchema = UserSchema.partial().required({ id: true });

type UpdateUser = z.infer<typeof UpdateUserSchema>;
// { id: string; name?: string; email?: string }

可组合架构

// 基础架构
const TimestampSchema = z.object({
  createdAt: z.date(),
  updatedAt: z.date(),
});

const AuthorSchema = z.object({
  authorId: z.string(),
  authorName: z.string(),
});

// 组合成更大的架构
const PostSchema = z.object({
  id: z.string(),
  title: z.string(),
  content: z.string(),
}).merge(TimestampSchema).merge(AuthorSchema);

生态系统集成

加载 references/ecosystem-integrations.md 获取完整的框架和工具集成指南。

快速参考

ESLint 插件:

  • eslint-plugin-zod-x - 强制执行最佳实践
  • eslint-plugin-import-zod - 强制执行导入样式

框架集成:

  • tRPC - 端到端类型安全 API
  • React Hook Form - 表单验证(参见 react-hook-form-zod 技能)
  • Prisma - 从数据库模型生成 Zod
  • NestJS - DTOs 和验证管道

代码生成:

  • orval - OpenAPI → Zod
  • Hey API - OpenAPI 到 TypeScript + Zod
  • kubb - 具有代码生成的 API 工具包

→ 加载 references/ecosystem-integrations.md 获取: 设置说明、集成示例、Hono 中间件、Drizzle ORM 模式

故障排除

加载 references/troubleshooting.md 获取完整的故障排除指南、性能提示和最佳实践。

快速参考

常见问题:

  1. TypeScript 严格模式必需 → 在 tsconfig.json 中启用
  2. 大包体积 → 使用 z.lazy() 进行代码拆分
  3. 异步优化慢 → 缓存或去抖动
  4. 循环依赖 → 使用 z.lazy()
  5. 联合类型慢 → 使用 z.discriminatedUnion()
  6. 转换与优化混淆 → 使用 .refine() 进行验证,.transform() 进行修改

性能提示:

  • 使用 .discriminatedUnion()(比 .union() 快 5-10 倍)
  • 缓存架构实例
  • 使用 .safeParse()(避免 try-catch 开销)
  • 懒加载大型架构

最佳实践:

  • 在模块级别定义架构
  • 使用类型推断(z.infer
  • 添加自定义错误消息
  • 在系统边界验证
  • 组合小型架构
  • 使用 .meta() 记录

→ 加载 references/troubleshooting.md 获取: 详细解决方案、性能优化、最佳实践、测试模式

快速参考

// 原始类型
z.string(), z.number(), z.boolean(), z.date(), z.bigint()

// 集合
z.array(), z.tuple(), z.object(), z.record(), z.map(), z.set()

// 特殊类型
z.enum(), z.union(), z.discriminatedUnion(), z.intersection()
z.literal(), z.any(), z.unknown(), z.never()

// 修饰符
.optional(), .nullable(), .nullish(), .default(), .catch()
.readonly(), .brand()

// 验证
.min(), .max(), .length(), .regex(), .email(), .url(), .uuid()
.refine(), .superRefine()

// 转换
.transform(), .pipe(), .codec()

// 解析
.parse(), .safeParse(), .parseAsync(), .safeParseAsync()

// 类型推断
z.infer<typeof Schema>, z.input<typeof Schema>, z.output<typeof Schema>

// 错误处理
z.flattenError(), z.treeifyError(), z.prettifyError()

// JSON Schema
z.toJSONSchema(schema, options)

// 元数据
.meta(), .describe()

// 对象方法
.extend(), .pick(), .omit(), .partial(), .required(), .merge()

何时加载参考文档

加载 references/migration-guide.md 当:

  • 从 Zod v3 升级到 v4
  • 有关破坏性更改的问题
  • 需要迁移清单或回滚策略
  • 与废弃 API 相关的错误(.merge(), error.format() 等)
  • 数字验证问题,如 Infinity 或不安全整数

加载 references/error-handling.md 当:

  • 需要为表单或 UI 格式化错误
  • 实现自定义错误消息
  • 有关 z.flattenError(), z.treeifyError(), 或 z.prettifyError() 的问题
  • 设置错误消息的本地化
  • 需要错误代码参考或模式示例

加载 references/advanced-patterns.md 当:

  • 实现自定义优化或异步验证
  • 需要双向转换(编解码器)
  • 处理递归类型或自引用数据
  • 有关 .refine(), .transform(), 或 .codec() 的问题
  • 需要性能优化模式
  • 实现条件验证

加载 references/type-inference.md 当:

  • 有关 TypeScript 类型推断的问题
  • 需要为 OpenAPI 或 AI 生成 JSON Schema
  • 为表单或文档实现元数据系统
  • 需要类型安全元数据的自定义注册表
  • 有关 z.infer, z.input, z.output 的问题
  • 使用品牌类型以确保 ID 安全

加载 references/ecosystem-integrations.md 当:

  • 与 tRPC、React Hook Form、Prisma 或 NestJS 集成
  • 为最佳实践设置 ESLint 插件
  • 从 OpenAPI 生成 Zod 架构(orval、Hey API、kubb)
  • 有关 Hono 中间件或 Drizzle ORM 的问题
  • 需要框架特定集成示例

加载 references/troubleshooting.md 当:

  • 遇到 TypeScript 严格模式错误
  • 包体积问题或懒加载需求
  • 大型联合或异步优化的性能问题
  • 循环依赖问题
  • 需要最佳实践或测试模式
  • .refine().transform() 的混淆

额外资源


生产说明:

  • 包版本: 4.1.12+ (Zod 4.x 稳定版)
  • 零依赖
  • 包体积: 2kb (压缩后)
  • TypeScript 5.5+ 必需
  • 严格模式必需
  • 最后验证: 2025-11-17
  • 技能版本: 2.0.0(更新了 v4.1 增强功能)

此版本新增内容:

  • ✨ 完整的 v3 到 v4 迁移指南,包含破坏性更改
  • ✨ 增强的错误定制系统,具有三级
  • ✨ 扩展的元数据 API 和注册表系统
  • ✨ 改进的错误格式化,附实用示例
  • ✨ 内置 40+ 语言本地化支持
  • ✨ 详细的编解码器文档和现实世界模式
  • ✨ 性能改进和架构更改解释