[ PROMPT_NODE_23772 ]
验证模式
[ SKILL_DOCUMENTATION ]
# 验证模式 - 使用 Zod 进行输入验证
使用 Zod 模式进行类型安全验证的完整指南。
## 目录
- [为什么选择 Zod?](#why-zod)
- [基础 Zod 模式](#basic-zod-patterns)
- [代码库中的模式示例](#schema-examples-from-codebase)
- [路由级验证](#route-level-validation)
- [控制器验证](#controller-validation)
- [DTO 模式](#dto-pattern)
- [错误处理](#error-handling)
- [高级模式](#advanced-patterns)
---
## 为什么选择 Zod?
### 相比 Joi/其他库的优势
**类型安全:**
- ✅ 完整的 TypeScript 推断
- ✅ 运行时 + 编译时验证
- ✅ 自动类型生成
**开发者体验:**
- ✅ 直观的 API
- ✅ 可组合的模式
- ✅ 出色的错误消息
**性能:**
- ✅ 快速验证
- ✅ 小包体积
- ✅ 可 Tree-shake
### 从 Joi 迁移
现代验证使用 Zod 代替 Joi:
typescript
// ❌ 旧版 - Joi(正在逐步淘汰)
const schema = Joi.object({
email: Joi.string().email().required(),
name: Joi.string().min(3).required(),
});
// ✅ 新版 - Zod(首选)
const schema = z.object({
email: z.string().email(),
name: z.string().min(3),
});
---
## 基础 Zod 模式
### 原始类型
typescript
import { z } from 'zod';
// 字符串
const nameSchema = z.string();
const emailSchema = z.string().email();
const urlSchema = z.string().url();
const uuidSchema = z.string().uuid();
const minLengthSchema = z.string().min(3);
const maxLengthSchema = z.string().max(100);
// 数字
const ageSchema = z.number().int().positive();
const priceSchema = z.number().positive();
const rangeSchema = z.number().min(0).max(100);
// 布尔值
const activeSchema = z.boolean();
// 日期
const dateSchema = z.string().datetime(); // ISO 8601 字符串
const nativeDateSchema = z.date(); // 原生 Date 对象
// 枚举
const roleSchema = z.enum(['admin', 'operations', 'user']);
const statusSchema = z.enum(['PENDING', 'APPROVED', 'REJECTED']);
### 对象
typescript
// 简单对象
const userSchema = z.object({
email: z.string().email(),
name: z.string(),
age: z.number().int().positive(),
});
// 嵌套对象
const addressSchema = z.object({
street: z.string(),
city: z.string(),
zipCode: z.string().regex(/^d{5}$/),
});
const userWithAddressSchema = z.object({
name: z.string(),
address: addressSchema,
});
// 可选字段
const userSchema = z.object({
name: z.string(),
email: z.stri