zod4
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseZod 4 Expert Guide
Zod 4 专家指南
Zod 4 is a major release with significant performance improvements, reduced TypeScript compilation times, and a cleaner API. This skill covers migration from v3 and idiomatic Zod 4 usage.
Zod 4 是一个重大版本,带来了显著的性能提升、更短的 TypeScript 编译时间以及更简洁的 API。本指南涵盖从 v3 迁移的方法和 Zod 4 的惯用用法。
Quick Migration Checklist
快速迁移清单
Before diving deep, address these high-impact breaking changes:
| Change | Zod 3 | Zod 4 |
|---|---|---|
| Record schemas | | |
| Strict objects | | |
| Passthrough | | |
| Error formatting | | |
| Coerce input type | | |
Install Zod 4:
bash
npm install zod@^4.0.0For detailed breaking changes, see ./reference/breaking-changes.md.
在深入了解之前,请先处理这些影响重大的破坏性变更:
| 变更 | Zod 3 | Zod 4 |
|---|---|---|
| Record 模式 | | |
| 严格对象 | | |
| 透传未知键 | | |
| 错误格式化 | | |
| 强制转换输入类型 | | |
安装 Zod 4:
bash
npm install zod@^4.0.0如需了解详细的破坏性变更,请查看 ./reference/breaking-changes.md。
Key Breaking Changes
主要破坏性变更
1. z.record() Requires Two Arguments
1. z.record() 需要两个参数
typescript
// Zod 3 (BROKEN in v4)
z.record(z.string());
// Zod 4 (REQUIRED)
z.record(z.string(), z.string());typescript
// Zod 3(在 v4 中失效)
z.record(z.string());
// Zod 4(必须写法)
z.record(z.string(), z.string());2. Strict/Loose Object Syntax
2. 严格/宽松对象语法
typescript
// Zod 3
z.object({ name: z.string() }).strict();
z.object({ name: z.string() }).passthrough();
// Zod 4
z.strictObject({ name: z.string() });
z.looseObject({ name: z.string() });typescript
// Zod 3
z.object({ name: z.string() }).strict();
z.object({ name: z.string() }).passthrough();
// Zod 4
z.strictObject({ name: z.string() });
z.looseObject({ name: z.string() });3. .default() Behavior Changed
3. .default() 行为变更
In Zod 4, short-circuits if input is and returns the default directly (without parsing). Use for the old behavior:
.default()undefined.prefault()typescript
// Zod 4: default must match OUTPUT type
const schema = z.string()
.transform(val => val.length)
.default(0); // Returns 0 directly, not parsed
// To parse the default (old behavior):
const schema = z.string()
.transform(val => val.length)
.prefault("tuna"); // "tuna" is parsed → 4在 Zod 4 中,若输入为 , 会直接返回默认值(不经过解析)。如需旧版行为,请使用 :
undefined.default().prefault()typescript
// Zod 4:默认值必须匹配输出类型
const schema = z.string()
.transform(val => val.length)
.default(0); // 直接返回 0,不经过解析
// 如需解析默认值(旧版行为):
const schema = z.string()
.transform(val => val.length)
.prefault("tuna"); // "tuna" 会被解析 → 44. Error Handling Changes
4. 错误处理变更
typescript
// Zod 3
const formatted = err.format();
const flat = err.flatten();
// Zod 4
const tree = z.treeifyError(err);
// Adding issues
err.issues.push({ /* new issue */ });typescript
// Zod 3
const formatted = err.format();
const flat = err.flatten();
// Zod 4
const tree = z.treeifyError(err);
// 添加错误信息
err.issues.push({ /* 新错误信息 */ });5. z.coerce Input Type
5. z.coerce 输入类型
typescript
const schema = z.coerce.string();
type Input = z.input<typeof schema>;
// Zod 3: string
// Zod 4: unknowntypescript
const schema = z.coerce.string();
type Input = z.input<typeof schema>;
// Zod 3: string
// Zod 4: unknownNew Features
新特性
z.file() - File Validation
z.file() - 文件验证
typescript
const fileSchema = z.file()
.min(10_000) // minimum bytes
.max(1_000_000) // maximum bytes
.mime(["image/png", "image/jpeg"]);typescript
const fileSchema = z.file()
.min(10_000) // 最小字节数
.max(1_000_000) // 最大字节数
.mime(["image/png", "image/jpeg"]);z.templateLiteral() - Template Literal Types
z.templateLiteral() - 模板字面量类型
typescript
const css = z.templateLiteral([z.number(), z.enum(["px", "em", "rem"])]);
// `${number}px` | `${number}em` | `${number}rem`
const email = z.templateLiteral([
z.string().min(1),
"@",
z.string().max(64),
]);typescript
const css = z.templateLiteral([z.number(), z.enum(["px", "em", "rem"])]);
// `${number}px` | `${number}em` | `${number}rem`
const email = z.templateLiteral([
z.string().min(1),
"@",
z.string().max(64),
]);.meta() - Schema Metadata
.meta() - 模式元数据
typescript
z.string().meta({
id: "email_address",
title: "Email address",
description: "User's email",
examples: ["user@example.com"]
});typescript
z.string().meta({
id: "email_address",
title: "Email address",
description: "User's email",
examples: ["user@example.com"]
});z.globalRegistry - Global Schema Registry
z.globalRegistry - 全局模式注册表
typescript
z.globalRegistry.add(mySchema, {
id: "user_schema",
title: "User",
description: "User data structure"
});typescript
z.globalRegistry.add(mySchema, {
id: "user_schema",
title: "User",
description: "User data structure"
});z.locales - Internationalization
z.locales - 国际化
typescript
import { z } from "zod";
import { en } from "zod/locales/en";
z.config(z.locales.en()); // Configure error messagestypescript
import { z } from "zod";
import { en } from "zod/locales/en";
z.config(z.locales.en()); // 配置错误提示信息z.strictObject() / z.looseObject()
z.strictObject() / z.looseObject()
typescript
// Rejects unknown keys
z.strictObject({ name: z.string() });
// Allows unknown keys (passthrough)
z.looseObject({ name: z.string() });For complete new features guide, see ./reference/new-features.md.
typescript
// 拒绝未知键
z.strictObject({ name: z.string() });
// 允许未知键(透传)
z.looseObject({ name: z.string() });如需完整的新特性指南,请查看 ./reference/new-features.md。
Zod Mini
Zod Mini
Zod Mini () provides a smaller bundle with tree-shakable, functional API:
zod/minitypescript
import * as z from "zod/mini";
// Functional checks instead of methods
const schema = z.pipe(
z.string(),
z.minLength(1),
z.maxLength(100),
z.regex(/^[a-z]+$/)
);
// Available functions
z.lt(value);
z.gt(value);
z.positive();
z.negative();
z.minLength(value);
z.maxLength(value);
z.regex(pattern);
z.trim();
z.toLowerCase();
z.toUpperCase();Zod Mini () 提供了一个体积更小的包,支持 tree-shaking,采用函数式 API:
zod/minitypescript
import * as z from "zod/mini";
// 使用函数式检查而非链式方法
const schema = z.pipe(
z.string(),
z.minLength(1),
z.maxLength(100),
z.regex(/^[a-z]+$/)
);
// 可用函数
z.lt(value);
z.gt(value);
z.positive();
z.negative();
z.minLength(value);
z.maxLength(value);
z.regex(pattern);
z.trim();
z.toLowerCase();
z.toUpperCase();Migration Patterns
迁移模式
Pattern 1: Update z.record() Calls
模式 1:更新 z.record() 调用
Search and replace:
typescript
// Find
z.record(valueSchema)
// Replace with
z.record(z.string(), valueSchema)搜索并替换:
typescript
// 查找
z.record(valueSchema)
// 替换为
z.record(z.string(), valueSchema)Pattern 2: Update Strict Objects
模式 2:更新严格对象
typescript
// Find
z.object({...}).strict()
// Replace with
z.strictObject({...})typescript
// 查找
z.object({...}).strict()
// 替换为
z.strictObject({...})Pattern 3: Update Error Handling
模式 3:更新错误处理
typescript
// Find
try {
schema.parse(data);
} catch (err) {
if (err instanceof z.ZodError) {
const formatted = err.format();
}
}
// Replace with
try {
schema.parse(data);
} catch (err) {
if (err instanceof z.ZodError) {
const tree = z.treeifyError(err);
}
}typescript
// 查找
try {
schema.parse(data);
} catch (err) {
if (err instanceof z.ZodError) {
const formatted = err.format();
}
}
// 替换为
try {
schema.parse(data);
} catch (err) {
if (err instanceof z.ZodError) {
const tree = z.treeifyError(err);
}
}Pattern 4: Fix Default Values
模式 4:修复默认值
If using with transforms, check if default matches output type:
.default()typescript
// If this breaks:
z.string().transform(s => s.length).default("hello")
// Change to:
z.string().transform(s => s.length).prefault("hello")
// OR
z.string().transform(s => s.length).default(5) // Match output typeFor complete migration checklist, see ./reference/migration-checklist.md.
如果在转换中使用 ,请检查默认值是否匹配输出类型:
.default()typescript
// 如果此代码失效:
z.string().transform(s => s.length).default("hello")
// 修改为:
z.string().transform(s => s.length).prefault("hello")
// 或者
z.string().transform(s => s.length).default(5) // 匹配输出类型如需完整的迁移清单,请查看 ./reference/migration-checklist.md。
Common Issues
常见问题
| Error | Cause | Fix |
|---|---|---|
| | Add key schema: |
| | Use |
| | Use |
Type mismatch on | Default must match output | Use |
| 错误 | 原因 | 修复方案 |
|---|---|---|
| | 添加键模式: |
| | 使用 |
| | 使用 |
| 默认值必须匹配输出类型 | 使用 |
Codemod
Codemod
A community-maintained codemod is available:
bash
npx zod-v3-to-v4This automates many of the breaking change fixes.
社区维护的 codemod 可用:
bash
npx zod-v3-to-v4这将自动修复许多破坏性变更问题。