使用 Zod 构建 TypeScript 类型安全的 Schema 验证
解决 TypeScript 开发中“定义两次”的痛点:通过 Zod 定义一次 Schema,同时获得运行时校验逻辑和静态类型推断,消除接口定义与验证代码不一致的问题。
为什么需要这个技能
在标准的 TypeScript 开发中,我们通常需要编写一个 interface 来定义类型,再编写一段验证逻辑(如 if 判断)来确保运行时数据正确。这种重复劳动不仅低效,且在 API 变更时极易导致两端不一致。
Zod 实现了“Schema 即类型”。它允许你定义一个验证模式,并使用 z.infer 自动提取出对应的 TypeScript 类型。这意味着你只需维护一份代码,即可在编译时获得类型提示,在运行时确保数据安全。
适用场景
- API 输入验证:对请求体(Request Body)或查询参数进行严格校验。
- 表单校验:结合 React Hook Form 实现端到端的类型安全表单。
- 环境变量管理:验证
process.env是否包含所有必要的配置项,防止应用启动后崩溃。 - 数据清洗与转换:将字符串形式的输入(如 FormData)自动转换为数字或日期对象。
- 复杂业务逻辑校验:实现跨字段验证(如确认密码一致性)。
核心工作流
1. 定义 Schema 与类型推断
使用 Zod 的原生类型定义规则,并通过 z.infer 导出类型,避免手动编写 interface。
import { z } from "zod";
const UserSchema = z.object({
id: z.string().uuid(),
username: z.string().min(3),
role: z.enum(["ADMIN", "USER"]).default("USER"),
age: z.coerce.number().min(18), // 将输入强制转换为数字
});
export type User = z.infer<typeof UserSchema>;
2. 执行解析与错误处理
推荐使用 safeParse 代替 parse,通过结果对象的 success 状态进行分支处理,避免大量的 try-catch 块。
const result = UserSchema.safeParse(inputData);
if (!result.success) {
// 提取可序列化的错误信息
console.log(result.error.flatten().fieldErrors);
} else {
const validData = result.data; // 此处 validData 已具有完全的类型定义
}
3. 高级校验与转换
利用 .refine 实现自定义逻辑,使用 .transform 在验证通过后改变数据形态。
const passwordSchema = z.object({
password: z.string().min(8),
confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
message: "两次输入的密码不一致",
path: ["confirmPassword"],
});
下载和安装
下载 zod-validation-expert 中文版 Skill ZIP
解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的 USAGE.zh.md。
你可能还需要
暂无推荐