Objects
Zod 提供了强大的对象验证功能。
基本用法
ts
import { z } from "zod";
const User = z.object({
username: z.string(),
age: z.number(),
email: z.string().email(),
isAdmin: z.boolean().optional(),
});
type User = z.infer<typeof User>;
// { username: string; age: number; email: string; isAdmin?: boolean }
访问对象属性
使用 .shape
访问对象的属性模式:
ts
const User = z.object({
username: z.string(),
age: z.number(),
});
User.shape.username; // 返回字符串模式
User.shape.age; // 返回数字模式
扩展对象
使用 .extend
添加新属性:
ts
const User = z.object({
username: z.string(),
});
const AdminUser = User.extend({
isAdmin: z.boolean(),
permissions: z.array(z.string()),
});
合并对象
使用 .merge
合并两个对象模式:
ts
const BaseUser = z.object({
id: z.string(),
username: z.string(),
});
const UserDetails = z.object({
age: z.number(),
email: z.string().email(),
});
const FullUser = BaseUser.merge(UserDetails);
// 等同于:
// z.object({
// id: z.string(),
// username: z.string(),
// age: z.number(),
// email: z.string().email(),
// })
部分选择和忽略
使用 .pick
和 .omit
选择或忽略特定属性:
ts
const User = z.object({
id: z.string(),
username: z.string(),
age: z.number(),
email: z.string(),
});
// 只选择某些字段
const UserBasics = User.pick({ username: true, age: true });
// { username: string; age: number }
// 忽略某些字段
const UserWithoutId = User.omit({ id: true });
// { username: string; age: number; email: string }
可选字段
使用 .partial
使所有字段变为可选:
ts
const User = z.object({
username: z.string(),
age: z.number(),
});
const PartialUser = User.partial();
// { username?: string; age?: number }
// 深度可选
const DeepPartialUser = User.deepPartial();
严格模式
默认情况下,Zod 会剔除未定义的字段。你可以使用 .strict()
禁止额外字段:
ts
const User = z.object({
username: z.string(),
}).strict();
User.parse({
username: "bob",
extra: "field", // 将抛出错误
});
// 或使用 .passthrough() 保留额外字段
const FlexibleUser = z.object({
username: z.string(),
}).passthrough();
FlexibleUser.parse({
username: "bob",
extra: "field", // 将被保留
});
通配符属性
使用 .catchall
定义未知键的类型:
ts
const NumberCache = z.object({
id: z.string(),
}).catchall(z.number());
// 等同于 { [k: string]: number } & { id: string }
NumberCache.parse({
id: "xyz123",
count: 42,
amount: 123,
}); // 通过