Tuples
Zod 提供了创建和验证元组的功能。元组是固定长度的数组,其中每个位置可以有不同的类型。
基本用法
ts
import { z } from "zod";
// 创建元组模式
const StringNumberTuple = z.tuple([z.string(), z.number()]);
type StringNumberTuple = z.infer<typeof StringNumberTuple>; // [string, number]
// 验证
StringNumberTuple.parse(["hello", 42]); // 通过
StringNumberTuple.parse(["hello", "world"]); // 失败
StringNumberTuple.parse([42, 42]); // 失败
可选元素
你可以使用 .rest()
方法来指定剩余元素的类型:
ts
const StringNumberRest = z.tuple([z.string(), z.number()]).rest(z.boolean());
// 验证
StringNumberRest.parse(["hello", 42]); // 通过
StringNumberRest.parse(["hello", 42, true]); // 通过
StringNumberRest.parse(["hello", 42, true, false]); // 通过
StringNumberRest.parse(["hello", 42, "true"]); // 失败
复杂元组
元组可以包含任何 Zod 模式:
ts
// 对象元组
const UserTuple = z.tuple([
z.object({ id: z.string() }),
z.object({ name: z.string() }),
]);
// 联合类型元组
const UnionTuple = z.tuple([
z.union([z.string(), z.number()]),
z.boolean(),
]);
// 嵌套元组
const NestedTuple = z.tuple([
z.tuple([z.string(), z.number()]),
z.boolean(),
]);
元组长度
元组的长度是固定的(除非使用 .rest()
):
ts
const Tuple = z.tuple([z.string(), z.number()]);
Tuple.parse(["hello", 42]); // 通过
Tuple.parse(["hello"]); // 失败:元组太短
Tuple.parse(["hello", 42, true]); // 失败:元组太长
元组元素访问
你可以使用数组索引访问元组的元素:
ts
const Tuple = z.tuple([z.string(), z.number(), z.boolean()]);
// 在 TypeScript 中
type First = z.infer<typeof Tuple>[0]; // string
type Second = z.infer<typeof Tuple>[1]; // number
type Third = z.infer<typeof Tuple>[2]; // boolean
自定义错误消息
你可以为元组的每个元素提供自定义错误消息:
ts
const Tuple = z.tuple([
z.string({
invalid_type_error: "第一个元素必须是字符串",
}),
z.number({
invalid_type_error: "第二个元素必须是数字",
}),
]);
// 验证
Tuple.parse([42, "hello"]); // 失败,带有自定义错误消息