Zod

TypeScript优先的模式验证库。类型安全,零依赖,运行时验证。

2020发布年份
Colin McDonnell作者

核心特性

Zod 的设计哲学和关键技术特性

🛡️ TypeScript优先

专为TypeScript设计,类型推断完美

⚡ 零依赖

无外部依赖,体积小,兼容性好

🔍 运行时验证

同时提供编译时类型和运行时验证

🎯 声明式API

简洁的链式API,易于阅读和维护

📦 模块化设计

支持自定义错误消息和验证逻辑

🔄 类型推断

从schema自动推断TypeScript类型

生态系统

Zod 核心扩展和官方工具

Zodios

基于Zod的API客户端,类型安全

API 客户端

React Hook Form + Zod

与React Hook Form完美集成

表单 验证

tRPC + Zod

全栈类型安全的RPC框架

全栈 类型安全

Prisma + Zod

数据库schema验证和类型生成

数据库 ORM

快速入门

# 安装Zod
npm install zod

# 基础用法
import { z } from 'zod'

// 定义schema
const userSchema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
  age: z.number().min(18).optional(),
})

// 类型推断
type User = z.infer<typeof userSchema>
// => { name: string; email: string; age?: number | undefined }

// 验证数据
const result = userSchema.safeParse({
  name: 'John',
  email: 'john@example.com',
  age: 25,
})

if (result.success) {
  console.log(result.data) // 验证通过的数据
} else {
  console.error(result.error) // 验证错误
}

配置示例

// 常用类型验证
import { z } from 'zod'

// 字符串验证
const stringSchema = z.string()
  .min(5, '至少5个字符')
  .max(50, '最多50个字符')
  .email('请输入有效的邮箱地址')

// 数字验证
const numberSchema = z.number()
  .min(0, '不能小于0')
  .max(100, '不能大于100')
  .int('必须是整数')

// 数组验证
const arraySchema = z.array(z.string())
  .min(1, '至少需要一个元素')
  .max(10, '最多10个元素')

// 对象验证
const addressSchema = z.object({
  street: z.string(),
  city: z.string(),
  zipCode: z.string().regex(/^\d{5}$/, '邮编格式错误'),
  country: z.string().default('中国'),
})

// 联合类型
const statusSchema = z.union([
  z.literal('active'),
  z.literal('inactive'),
  z.literal('pending'),
])

// 枚举类型
const roleSchema = z.enum(['admin', 'user', 'guest'])

// 可选和可空
const optionalSchema = z.string().optional()
const nullableSchema = z.string().nullable()
const nullishSchema = z.string().nullish() // optional + nullable

// 自定义验证
const passwordSchema = z.string()
  .min(8, '密码至少8位')
  .regex(/[A-Z]/, '需要包含大写字母')
  .regex(/[0-9]/, '需要包含数字')
  .regex(/[^A-Za-z0-9]/, '需要包含特殊字符')

// 表单验证示例
const loginSchema = z.object({
  username: z.string().min(3, '用户名至少3个字符'),
  password: passwordSchema,
  rememberMe: z.boolean().default(false),
})

type LoginFormData = z.infer<typeof loginSchema>

学习资源

与其他验证库对比

vs Yup

ZodTypeScript优先,类型推断更好。Yup更成熟,社区更大。

vs Joi

Zod更轻量,TypeScript支持更好。Joi更重,功能更全但体积大。