zod

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zod: TypeScript-First Schema Validation

Zod:以TypeScript优先的Schema验证库

Overview

概述

Zod is a TypeScript-first validation library that enables developers to define schemas for validating data at runtime while automatically inferring static TypeScript types. With zero dependencies and a 2kb core bundle (gzipped), Zod provides immutable, composable validation with comprehensive error handling.
Zod是一个以TypeScript优先的验证库,允许开发者定义Schema以在运行时验证数据,同时自动推断静态TypeScript类型。Zod零依赖,核心包压缩后仅2kb,提供不可变、可组合的验证能力以及全面的错误处理机制。

Installation

安装

bash
bun add zod
bash
bun add zod

or

or

bun add zod
bun add zod

or

or

bun add zod
bun add zod

or

or

yarn add zod

**Requirements**:
- TypeScript v5.5+ with `"strict": true` in `tsconfig.json`
- Zod 4.x (4.1.12+)

**Important**: This skill documents **Zod 4.x** features. The following APIs require Zod 4 and are NOT available in Zod 3.x:
- `z.codec()` - Bidirectional transformations
- `z.iso.date()`, `z.iso.time()`, `z.iso.datetime()`, `z.iso.duration()` - ISO format validators
- `z.toJSONSchema()` - JSON Schema generation
- `z.treeifyError()`, `z.prettifyError()`, `z.flattenError()` - New error formatting helpers
- `.meta()` - Enhanced metadata (Zod 3.x only has `.describe()`)
- Unified `error` parameter - Replaces `message`, `invalid_type_error`, `required_error`, `errorMap`

For Zod 3.x compatibility or migration guidance, see https://zod.dev
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

Migrating from Zod v3 to v4

从Zod v3迁移到v4

Load
references/migration-guide.md
for complete v3 to v4 migration documentation.
加载
references/migration-guide.md
以获取完整的v3到v4迁移文档。

Quick Summary

快速摘要

Zod v4 introduces breaking changes for better performance:
  • Error customization: Use unified
    error
    parameter (replaces
    message
    ,
    invalid_type_error
    ,
    required_error
    )
  • Number validation: Stricter - rejects
    Infinity
    and unsafe integers
  • String formats: Now top-level functions (
    z.email()
    vs
    z.string().email()
    )
  • Object defaults: Applied even in optional fields
  • Deprecated APIs: Use
    .extend()
    (not
    .merge()
    ),
    z.treeifyError()
    (not
    error.format()
    )
  • Function validation: Use
    .implement()
    method
  • UUID validation: Stricter RFC 9562/4122 compliance
→ Load
references/migration-guide.md
for:
Complete breaking changes, migration checklist, gradual migration strategy, rollback instructions
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
查看:
完整的破坏性变更、迁移清单、渐进式迁移策略、回滚说明

Core Concepts

核心概念

Basic Usage Pattern

基础使用模式

typescript
import { z } from "zod";

// Define schema
const UserSchema = z.object({
  username: z.string(),
  age: z.number().int().positive(),
  email: z.string().email(),
});

// Infer TypeScript type
type User = z.infer<typeof UserSchema>;

// Validate data (throws on error)
const user = UserSchema.parse(data);

// Validate data (returns result object)
const result = UserSchema.safeParse(data);
if (result.success) {
  console.log(result.data); // Typed!
} else {
  console.error(result.error); // ZodError
}
typescript
import { z } from "zod";

// 定义Schema
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
}

Parsing Methods

解析方法

Use the appropriate parsing method based on error handling needs:
  • .parse(data)
    - Throws
    ZodError
    on invalid input; returns strongly-typed data on success
  • .safeParse(data)
    - Returns
    { success: true, data }
    or
    { success: false, error }
    (no exceptions)
  • .parseAsync(data)
    - For schemas with async refinements/transforms
  • .safeParseAsync(data)
    - Async version that doesn't throw
Best Practice: Use
.safeParse()
to avoid try-catch blocks and leverage discriminated unions.
根据错误处理需求选择合适的解析方法:
  • .parse(data)
    - 输入无效时抛出
    ZodError
    ;成功时返回强类型数据
  • .safeParse(data)
    - 返回
    { success: true, data }
    { success: false, error }
    (不抛出异常)
  • .parseAsync(data)
    - 适用于包含异步细化/转换的Schema
  • .safeParseAsync(data)
    - 异步版本,不会抛出异常
最佳实践:使用
.safeParse()
避免try-catch代码块,利用区分联合类型的优势。

Primitive Types

原始类型

Strings

字符串

typescript
z.string()                    // Basic string
z.string().min(5)            // Minimum length
z.string().max(100)          // Maximum length
z.string().length(10)        // Exact length
z.string().email()           // Email validation
z.string().url()             // URL validation
z.string().uuid()            // UUID format
z.string().regex(/^\d+$/)    // Custom pattern
z.string().startsWith("pre") // Prefix check
z.string().endsWith("suf")   // Suffix check
z.string().trim()            // Auto-trim whitespace
z.string().toLowerCase()     // Auto-lowercase
z.string().toUpperCase()     // Auto-uppercase

// ISO formats (Zod 4+)
z.iso.date()                 // YYYY-MM-DD
z.iso.time()                 // HH:MM:SS
z.iso.datetime()             // ISO 8601 datetime
z.iso.duration()             // ISO 8601 duration

// Network formats
z.ipv4()                     // IPv4 address
z.ipv6()                     // IPv6 address
z.cidrv4()                   // IPv4 CIDR notation
z.cidrv6()                   // IPv6 CIDR notation

// Other formats
z.jwt()                      // JWT token
z.nanoid()                   // Nanoid
z.cuid()                     // CUID
z.cuid2()                    // CUID2
z.ulid()                     // ULID
z.base64()                   // Base64 encoded
z.hex()                      // Hexadecimal
typescript
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()                      // 十六进制

Numbers

数字

typescript
z.number()                   // Basic number
z.number().int()             // Integer only
z.number().positive()        // > 0
z.number().nonnegative()     // >= 0
z.number().negative()        // < 0
z.number().nonpositive()     // <= 0
z.number().min(0)            // Minimum value
z.number().max(100)          // Maximum value
z.number().gt(0)             // Greater than
z.number().gte(0)            // Greater than or equal
z.number().lt(100)           // Less than
z.number().lte(100)          // Less than or equal
z.number().multipleOf(5)     // Must be multiple of 5
z.int()                      // Shorthand for z.number().int()
z.int32()                    // 32-bit integer
z.nan()                      // NaN value
typescript
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值

Coercion (Type Conversion)

类型转换

typescript
z.coerce.string()            // Convert to string
z.coerce.number()            // Convert to number
z.coerce.boolean()           // Convert to boolean
z.coerce.bigint()            // Convert to bigint
z.coerce.date()              // Convert to Date

// Example: Parse query parameters
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 }
typescript
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 }

Other Primitives

其他原始类型

typescript
z.boolean()                  // Boolean
z.date()                     // Date object
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)
typescript
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)

Complex Types

复杂类型

Objects

对象

typescript
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>;

// Object methods
PersonSchema.shape                 // Access shape
PersonSchema.keyof()              // Get union of keys
PersonSchema.extend({ role: z.string() })  // Add fields
PersonSchema.pick({ name: true }) // Pick specific fields
PersonSchema.omit({ age: true })  // Omit fields
PersonSchema.partial()            // Make all fields optional
PersonSchema.required()           // Make all fields required
PersonSchema.deepPartial()        // Recursively optional

// Strict vs loose objects
z.strictObject({ ... })           // No extra keys allowed (throws)
z.object({ ... })                 // Strips extra keys (default)
z.looseObject({ ... })            // Allows extra keys
typescript
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({ ... })            // 允许额外键

Arrays

数组

typescript
z.array(z.string())              // String array
z.array(z.number()).min(1)       // At least 1 element
z.array(z.number()).max(10)      // At most 10 elements
z.array(z.number()).length(5)    // Exactly 5 elements
z.array(z.number()).nonempty()   // At least 1 element

// Nested arrays
z.array(z.array(z.number()))     // number[][]
typescript
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[][]

Tuples

元组

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

Enums and Literals

枚举与字面量

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

// Literal values
z.literal("exact_value")
z.literal(42)
z.literal(true)

// Native TypeScript enum
enum Fruits {
  Apple,
  Banana,
}
z.nativeEnum(Fruits)

// Enum methods
RoleEnum.enum.admin              // "admin"
RoleEnum.exclude(["guest"])      // Exclude values
RoleEnum.extract(["admin", "user"]) // Include only
typescript
// 枚举
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"]) // 仅保留指定值

Unions

联合类型

typescript
// Basic union
z.union([z.string(), z.number()])

// Discriminated union (better performance & type inference)
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 }
typescript
// 基础联合类型
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 }

Intersections

交叉类型

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

const Combined = z.intersection(BaseSchema, ExtendedSchema);
// Equivalent to: z.object({ id: z.string(), name: z.string() })
typescript
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() })

Records and Maps

记录与映射

typescript
// Record: object with typed keys and values
z.record(z.string())             // { [key: string]: string }
z.record(z.string(), z.number()) // { [key: string]: number }

// Partial record (some keys optional)
z.partialRecord(z.enum(["a", "b"]), z.string())

// Map
z.map(z.string(), z.number())    // Map<string, number>
z.set(z.string())                // Set<string>
typescript
// Record:键和值均为指定类型的对象
z.record(z.string())             // { [key: string]: string }
z.record(z.string(), z.number()) // { [key: string]: number }

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

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

Advanced Patterns

高级模式

Load
references/advanced-patterns.md
for complete advanced validation and transformation patterns.
加载
references/advanced-patterns.md
以获取完整的高级验证与转换模式文档。

Quick Reference

快速参考

Refinements (custom validation):
typescript
z.string().refine((val) => val.length >= 8, "Too short");
z.object({ password, confirmPassword }).superRefine((data, ctx) => { /* ... */ });
Transformations (modify data):
typescript
z.string().transform((val) => val.trim());
z.string().pipe(z.coerce.number());
Codecs (bidirectional transforms - NEW in v4.1):
typescript
const DateCodec = z.codec(
  z.iso.datetime(),
  z.date(),
  {
    decode: (str) => new Date(str),
    encode: (date) => date.toISOString(),
  }
);
Recursive Types:
typescript
const CategorySchema: z.ZodType<Category> = z.lazy(() =>
  z.object({ name: z.string(), subcategories: z.array(CategorySchema) })
);
Optional/Nullable:
typescript
z.string().optional()            // string | undefined
z.string().nullable()            // string | null
z.string().default("default")    // Provides default if undefined
Readonly & Brand:
typescript
z.object({ ... }).readonly()     // Readonly properties
z.string().brand<"UserId">()     // Nominal typing
→ Load
references/advanced-patterns.md
for:
Complete refinement patterns, async validation, codec examples, composable schemas, conditional validation, performance optimization
细化验证(自定义验证):
typescript
z.string().refine((val) => val.length >= 8, "Too short");
z.object({ password, confirmPassword }).superRefine((data, ctx) => { /* ... */ });
转换(修改数据):
typescript
z.string().transform((val) => val.trim());
z.string().pipe(z.coerce.number());
Codec(双向转换 - v4.1新增):
typescript
const DateCodec = z.codec(
  z.iso.datetime(),
  z.date(),
  {
    decode: (str) => new Date(str),
    encode: (date) => date.toISOString(),
  }
);
递归类型
typescript
const CategorySchema: z.ZodType<Category> = z.lazy(() =>
  z.object({ name: z.string(), subcategories: z.array(CategorySchema) })
);
可选/可空
typescript
z.string().optional()            // string | undefined
z.string().nullable()            // string | null
z.string().default("default")    // 当值为undefined时使用默认值
只读与品牌类型
typescript
z.object({ ... }).readonly()     // 只读属性
z.string().brand<"UserId">()     // 标称类型
→ 加载
references/advanced-patterns.md
查看:
完整的细化验证模式、异步验证、Codec示例、可组合Schema、条件验证、性能优化

Error Handling

错误处理

Load
references/error-handling.md
for complete error formatting and customization guide.
加载
references/error-handling.md
以获取完整的错误格式化与自定义指南。

Quick Reference

快速参考

Error Formatting Methods:
typescript
// For forms
const { fieldErrors } = z.flattenError(error);

// For nested data
const tree = z.treeifyError(error);
const nameError = tree.properties?.user?.properties?.name?.errors?.[0];

// For debugging
console.log(z.prettifyError(error));
Custom Error Messages (three levels):
typescript
// 1. Schema-level (highest priority)
z.string({ error: "Custom message" });
z.string().min(5, "Too short");

// 2. Per-parse level
schema.parse(data, { error: (issue) => ({ message: "..." }) });

// 3. Global level
z.config({ customError: (issue) => ({ message: "..." }) });
Localization (40+ languages):
typescript
z.config(z.locales.es());  // Spanish
z.config(z.locales.fr());  // French
→ Load
references/error-handling.md
for:
Complete error formatting examples, custom error patterns, localization setup, error code reference
错误格式化方法
typescript
// 适用于表单
const { fieldErrors } = z.flattenError(error);

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

// 适用于调试
console.log(z.prettifyError(error));
自定义错误消息(三个层级):
typescript
// 1. Schema层级(优先级最高)
z.string({ error: "Custom message" });
z.string().min(5, "Too short");

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

// 3. 全局层级
z.config({ customError: (issue) => ({ message: "..." }) });
本地化(支持40+种语言):
typescript
z.config(z.locales.es());  // 西班牙语
z.config(z.locales.fr());  // 法语
→ 加载
references/error-handling.md
查看:
完整的错误格式化示例、自定义错误模式、本地化设置、错误代码参考

Type Inference

类型推断

Load
references/type-inference.md
for complete type inference and metadata documentation.
加载
references/type-inference.md
以获取完整的类型推断与元数据文档。

Quick Reference

快速参考

Basic Type Inference:
typescript
const UserSchema = z.object({ name: z.string() });
type User = z.infer<typeof UserSchema>; // { name: string }
Input vs Output (for transforms):
typescript
const TransformSchema = z.string().transform((s) => s.length);
type Input = z.input<typeof TransformSchema>;   // string
type Output = z.output<typeof TransformSchema>; // number
JSON Schema Conversion:
typescript
const jsonSchema = z.toJSONSchema(UserSchema, {
  target: "openapi-3.0",
  metadata: true,
});
Metadata:
typescript
// Add metadata
const EmailSchema = z.string().email().meta({
  title: "Email Address",
  description: "User's email address",
});

// Create custom registry
const formRegistry = z.registry<FormFieldMeta>();
→ Load
references/type-inference.md
for:
Complete type inference patterns, JSON Schema options, metadata system, custom registries, brand types
基础类型推断
typescript
const UserSchema = z.object({ name: z.string() });
type User = z.infer<typeof UserSchema>; // { name: string }
输入与输出类型(针对转换操作):
typescript
const TransformSchema = z.string().transform((s) => s.length);
type Input = z.input<typeof TransformSchema>;   // string
type Output = z.output<typeof TransformSchema>; // number
JSON Schema转换
typescript
const jsonSchema = z.toJSONSchema(UserSchema, {
  target: "openapi-3.0",
  metadata: true,
});
元数据
typescript
// 添加元数据
const EmailSchema = z.string().email().meta({
  title: "Email Address",
  description: "User's email address",
});

// 创建自定义注册表
const formRegistry = z.registry<FormFieldMeta>();
→ 加载
references/type-inference.md
查看:
完整的类型推断模式、JSON Schema选项、元数据系统、自定义注册表、品牌类型

Functions

函数验证

Validate function inputs and outputs:
typescript
const AddFunction = z.function()
  .args(z.number(), z.number())  // Arguments
  .returns(z.number());           // Return type

// Implement typed function
const add = AddFunction.implement((a, b) => {
  return a + b; // Type-checked!
});

// Async functions
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();
  });
验证函数的输入与输出:
typescript
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();
  });

Common Patterns

常见使用模式

Environment Variables

环境变量验证

typescript
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),
});

// Validate on startup
const env = EnvSchema.parse(process.env);

// Now use typed env
console.log(env.PORT); // number
typescript
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);

// 现在可以使用带类型的env
console.log(env.PORT); // number类型

API Request Validation

API请求验证

typescript
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 example
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);
});
typescript
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);
});

Form Validation

表单验证

typescript
const FormSchema = z.object({
  firstName: z.string().min(1, "First name required"),
  lastName: z.string().min(1, "Last name required"),
  email: z.string().email("Invalid email"),
  age: z.coerce.number().int().min(18, "Must be 18+"),
  agreeToTerms: z.literal(true, {
    errorMap: () => ({ message: "Must accept terms" }),
  }),
});

type FormData = z.infer<typeof FormSchema>;
typescript
const FormSchema = z.object({
  firstName: z.string().min(1, "First name required"),
  lastName: z.string().min(1, "Last name required"),
  email: z.string().email("Invalid email"),
  age: z.coerce.number().int().min(18, "Must be 18+"),
  agreeToTerms: z.literal(true, {
    errorMap: () => ({ message: "Must accept terms" }),
  }),
});

type FormData = z.infer<typeof FormSchema>;

Partial Updates

部分更新

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

// For PATCH requests: make everything optional except id
const UpdateUserSchema = UserSchema.partial().required({ id: true });

type UpdateUser = z.infer<typeof UpdateUserSchema>;
// { id: string; name?: string; email?: string }
typescript
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 }

Composable Schemas

可组合Schema

typescript
// Base schemas
const TimestampSchema = z.object({
  createdAt: z.date(),
  updatedAt: z.date(),
});

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

// Compose into larger schemas
const PostSchema = z.object({
  id: z.string(),
  title: z.string(),
  content: z.string(),
}).merge(TimestampSchema).merge(AuthorSchema);
typescript
// 基础Schema
const TimestampSchema = z.object({
  createdAt: z.date(),
  updatedAt: z.date(),
});

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

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

Ecosystem Integration

生态系统集成

Load
references/ecosystem-integrations.md
for complete framework and tooling integration guide.
加载
references/ecosystem-integrations.md
以获取完整的框架与工具集成指南。

Quick Reference

快速参考

ESLint Plugins:
  • eslint-plugin-zod-x
    - Enforces best practices
  • eslint-plugin-import-zod
    - Enforces import style
Framework Integrations:
  • tRPC - End-to-end typesafe APIs
  • React Hook Form - Form validation (see
    react-hook-form-zod
    skill)
  • Prisma - Generate Zod from database models
  • NestJS - DTOs and validation pipes
Code Generation:
  • orval - OpenAPI → Zod
  • Hey API - OpenAPI to TypeScript + Zod
  • kubb - API toolkit with codegen
→ Load
references/ecosystem-integrations.md
for:
Setup instructions, integration examples, Hono middleware, Drizzle ORM patterns
ESLint插件:
  • eslint-plugin-zod-x
    - 强制执行最佳实践
  • eslint-plugin-import-zod
    - 规范导入风格
框架集成:
  • tRPC - 端到端类型安全API
  • React Hook Form - 表单验证(查看
    react-hook-form-zod
    技能)
  • Prisma - 从数据库模型生成Zod Schema
  • NestJS - DTO与验证管道
代码生成:
  • orval - OpenAPI → Zod
  • Hey API - OpenAPI转TypeScript + Zod
  • kubb - 带代码生成的API工具包
→ 加载
references/ecosystem-integrations.md
查看:
设置说明、集成示例、Hono中间件、Drizzle ORM模式

Troubleshooting

故障排除

Load
references/troubleshooting.md
for complete troubleshooting guide, performance tips, and best practices.
加载
references/troubleshooting.md
以获取完整的故障排除指南、性能优化技巧与最佳实践。

Quick Reference

快速参考

Common Issues:
  1. TypeScript strict mode required → Enable in
    tsconfig.json
  2. Large bundle size → Use
    z.lazy()
    for code splitting
  3. Slow async refinements → Cache or debounce
  4. Circular dependencies → Use
    z.lazy()
  5. Slow unions → Use
    z.discriminatedUnion()
  6. Transform vs refine confusion → Use
    .refine()
    for validation,
    .transform()
    for modification
Performance Tips:
  • Use
    .discriminatedUnion()
    (5-10x faster than
    .union()
    )
  • Cache schema instances
  • Use
    .safeParse()
    (avoids try-catch overhead)
  • Lazy load large schemas
Best Practices:
  • Define schemas at module level
  • Use type inference (
    z.infer
    )
  • Add custom error messages
  • Validate at system boundaries
  • Compose small schemas
  • Document with
    .meta()
→ Load
references/troubleshooting.md
for:
Detailed solutions, performance optimization, best practices, testing patterns
常见问题:
  1. 要求TypeScript严格模式 → 在
    tsconfig.json
    中启用
  2. 包体积过大 → 使用
    z.lazy()
    进行代码拆分
  3. 异步细化验证缓慢 → 缓存或防抖
  4. 循环依赖 → 使用
    z.lazy()
  5. 联合类型性能差 → 使用
    z.discriminatedUnion()
  6. 混淆transform与refine → 使用
    .refine()
    进行验证,
    .transform()
    进行数据修改
性能优化技巧:
  • 使用
    .discriminatedUnion()
    (比
    .union()
    快5-10倍)
  • 缓存Schema实例
  • 使用
    .safeParse()
    (避免try-catch开销)
  • 懒加载大型Schema
最佳实践:
  • 在模块级别定义Schema
  • 使用类型推断(
    z.infer
  • 添加自定义错误消息
  • 在系统边界处进行验证
  • 组合小型Schema
  • 使用
    .meta()
    添加文档
→ 加载
references/troubleshooting.md
查看:
详细解决方案、性能优化、最佳实践、测试模式

Quick Reference

快速参考

typescript
// Primitives
z.string(), z.number(), z.boolean(), z.date(), z.bigint()

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

// Special types
z.enum(), z.union(), z.discriminatedUnion(), z.intersection()
z.literal(), z.any(), z.unknown(), z.never()

// Modifiers
.optional(), .nullable(), .nullish(), .default(), .catch()
.readonly(), .brand()

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

// Transformation
.transform(), .pipe(), .codec()

// Parsing
.parse(), .safeParse(), .parseAsync(), .safeParseAsync()

// Type inference
z.infer<typeof Schema>, z.input<typeof Schema>, z.output<typeof Schema>

// Error handling
z.flattenError(), z.treeifyError(), z.prettifyError()

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

// Metadata
.meta(), .describe()

// Object methods
.extend(), .pick(), .omit(), .partial(), .required(), .merge()
typescript
// 原始类型
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()

When to Load References

何时加载参考文档

Load
references/migration-guide.md
when:
  • Upgrading from Zod v3 to v4
  • Questions about breaking changes
  • Need migration checklist or rollback strategy
  • Errors related to deprecated APIs (
    .merge()
    ,
    error.format()
    , etc.)
  • Number validation issues with
    Infinity
    or unsafe integers
Load
references/error-handling.md
when:
  • Need to format errors for forms or UI
  • Implementing custom error messages
  • Questions about
    z.flattenError()
    ,
    z.treeifyError()
    , or
    z.prettifyError()
  • Setting up localization for error messages
  • Need error code reference or pattern examples
Load
references/advanced-patterns.md
when:
  • Implementing custom refinements or async validation
  • Need bidirectional transformations (codecs)
  • Working with recursive types or self-referential data
  • Questions about
    .refine()
    ,
    .transform()
    , or
    .codec()
  • Need performance optimization patterns
  • Implementing conditional validation
Load
references/type-inference.md
when:
  • Questions about TypeScript type inference
  • Need to generate JSON Schema for OpenAPI or AI
  • Implementing metadata system for forms or documentation
  • Need custom registries for type-safe metadata
  • Questions about
    z.infer
    ,
    z.input
    ,
    z.output
  • Using brand types for ID safety
Load
references/ecosystem-integrations.md
when:
  • Integrating with tRPC, React Hook Form, Prisma, or NestJS
  • Setting up ESLint plugins for best practices
  • Generating Zod schemas from OpenAPI (orval, Hey API, kubb)
  • Questions about Hono middleware or Drizzle ORM
  • Need framework-specific integration examples
Load
references/troubleshooting.md
when:
  • Encountering TypeScript strict mode errors
  • Bundle size concerns or lazy loading needs
  • Performance issues with large unions or async refinements
  • Questions about circular dependencies
  • Need best practices or testing patterns
  • Confusion between
    .refine()
    and
    .transform()
加载
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
的场景
:
  • 实现自定义细化验证或异步验证
  • 需要双向转换(Codec)
  • 处理递归类型或自引用数据
  • 关于
    .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 Schema(orval、Hey API、kubb)
  • 关于Hono中间件或Drizzle ORM的疑问
  • 需要框架特定的集成示例
加载
references/troubleshooting.md
的场景
:
  • 遇到TypeScript严格模式错误
  • 包体积过大或需要懒加载
  • 大型联合类型或异步细化验证的性能问题
  • 关于循环依赖的疑问
  • 需要最佳实践或测试模式
  • 混淆
    .refine()
    .transform()

Additional Resources

额外资源


Production Notes:
  • Package version: 4.1.12+ (Zod 4.x stable)
  • Zero dependencies
  • Bundle size: 2kb (gzipped)
  • TypeScript 5.5+ required
  • Strict mode required
  • Last verified: 2025-11-17
  • Skill version: 2.0.0 (Updated with v4.1 enhancements)
What's New in This Version:
  • ✨ Comprehensive v3 to v4 migration guide with breaking changes
  • ✨ Enhanced error customization with three-level system
  • ✨ Expanded metadata API with registry system
  • ✨ Improved error formatting with practical examples
  • ✨ Built-in localization support for 40+ locales
  • ✨ Detailed codec documentation with real-world patterns
  • ✨ Performance improvements and architectural changes explained

生产环境注意事项:
  • 包版本: 4.1.12+(Zod 4.x稳定版)
  • 零依赖
  • 包体积: 2kb(压缩后)
  • 要求TypeScript 5.5+
  • 要求启用严格模式
  • 最后验证时间: 2025-11-17
  • 技能版本: 2.0.0(已更新v4.1增强特性)
本版本新增内容:
  • ✨ 完整的v3到v4迁移指南,包含破坏性变更说明
  • ✨ 三级系统的增强型错误自定义
  • ✨ 带注册表系统的扩展元数据API
  • ✨ 实用示例的改进型错误格式化
  • ✨ 内置对40+种语言的本地化支持
  • ✨ 带真实场景的详细Codec文档
  • ✨ 性能优化与架构变更说明