mcpField
Z
zod4

zod4

github.com/kastalien-research开发9289 次安装42 周前更新
代码仓库

关于 zod4

面向使用 Zod 4 的 TypeScript 开发者,提供版本迁移与惯用用法指南。内容涵盖破坏性变更、新功能和常见问题,帮助更新现有代码并编写符合新 API 的模式。

主要功能

  1. 01Zod 3 到 Zod 4 迁移指引
  2. 02破坏性变更与常见问题说明
  3. 03文件、模板字面量等新功能
  4. 04Zod Mini 与函数式 API 示例
  5. 05迁移清单与 codemod 说明

适用场景

  1. 01将项目从 Zod 3 升级到 Zod 4
  2. 02调整 record、对象和错误处理代码
  3. 03采用 Zod 4 新增的校验能力
  4. 04排查默认值和类型相关问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kastalien-research/thoughtbox-dot-claude --skill zod4

安装后在 Claude Code 中输入/zod4确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
breaking-changes.md
migration-checklist.md
new-features.md

详细介绍

Zod 4 专家指南

Zod 4 是一个重大版本,带来了显著的性能提升、更短的 TypeScript 编译时间,以及更简洁的 API。本指南介绍从 v3 迁移以及符合惯用方式的 Zod 4 用法。

快速迁移清单

深入了解之前,请先处理以下影响较大的破坏性变更:

变更Zod 3Zod 4
Record 模式z.record(z.string())z.record(z.string(), z.string())
严格对象.strict()z.strictObject({...})
透传.passthrough()z.looseObject({...})
错误格式化err.format()z.treeifyError(err)
强制转换输入类型stringunknown

安装 Zod 4:

npm install zod@^4.0.0

如需了解详细的破坏性变更,请参阅 ./reference/breaking-changes.md。


主要破坏性变更

1. z.record() 需要两个参数
// Zod 3 (BROKEN in v4)
z.record(z.string());

// Zod 4 (REQUIRED)
z.record(z.string(), z.string());
2. 严格/宽松对象语法
// 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() 行为已更改

在 Zod 4 中,如果输入为 undefined,.default() 会直接返回默认值,而不进行解析。若要使用旧行为,请改用 .prefault():

// 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
4. 错误处理变更
// Zod 3
const formatted = err.format();
const flat = err.flatten();

// Zod 4
const tree = z.treeifyError(err);

// Adding issues
err.issues.push({ /* new issue */ });
5. z.coerce 输入类型
const schema = z.coerce.string();
type Input = z.input<typeof schema>;
// Zod 3: string
// Zod 4: unknown

新功能

z.file() - 文件验证
const fileSchema = z.file()
  .min(10_000)        // minimum bytes
  .max(1_000_000)     // maximum bytes
  .mime(["image/png", "image/jpeg"]);
z.templateLiteral() - 模板字面量类型
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() - 模式元数据
z.string().meta({
  id: "email_address",
  title: "Email address",
  description: "User's email",
  examples: ["[email protected]"]
});
z.globalRegistry - 全局模式注册表
z.globalRegistry.add(mySchema, {
  id: "user_schema",
  title: "User",
  description: "User data structure"
});
z.locales - 国际化
import { z } from "zod";
import { en } from "zod/locales/en";

z.config(z.locales.en());  // Configure error messages
z.strictObject() / z.looseObject()
// Rejects unknown keys
z.strictObject({ name: z.string() });

// Allows unknown keys (passthrough)
z.looseObject({ name: z.string() });

如需查看完整的新功能指南,请参阅 ./reference/new-features.md。


Zod Mini

Zod Mini(zod/mini)提供更小的打包体积,并采用可进行 tree-shaking 的函数式 API:

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();

迁移模式

模式 1:更新 z.record() 调用

搜索并替换:

// Find
z.record(valueSchema)

// Replace with
z.record(z.string(), valueSchema)
模式 2:更新严格对象
// Find
z.object({...}).strict()

// Replace with
z.strictObject({...})
模式 3:更新错误处理
// 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);
  }
}
模式 4:修正默认值

如果在转换中使用 .default(),请检查默认值是否与输出类型匹配:

// 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 type

如需查看完整的迁移清单,请参阅 ./reference/migration-checklist.md。


常见问题

错误原因修复方法
Expected 2 arguments, got 1z.record() 仅传入一个参数添加键模式:z.record(z.string(), ...)
Property 'strict' does not exist.strict() 已移除使用 z.strictObject()
Property 'format' does not exist.format() 已移除使用 z.treeifyError(err)
.default() 类型不匹配默认值必须与输出类型匹配使用 .prefault() 或修正默认值类型

Codemod

有一个由社区维护的 codemod 可供使用:

npx zod-v3-to-v4

它可以自动处理许多破坏性变更修复。


资源

评论

支持 Markdown