Unions
Zod 提供了内置的 z.union
方法来创建联合类型。
基本用法
ts
import { z } from "zod";
// 创建联合类型
const stringOrNumber = z.union([z.string(), z.number()]);
stringOrNumber.parse("hello"); // 通过
stringOrNumber.parse(42); // 通过
stringOrNumber.parse(true); // 失败
使用 .or() 方法
为了方便,你也可以使用 .or()
方法:
ts
const stringOrNumber = z.string().or(z.number());
const stringOrNumberOrBoolean = z.string()
.or(z.number())
.or(z.boolean());
判别联合类型
判别联合类型是指联合类型中的每个成员都有一个共同的、具有不同值的属性:
ts
const result = z.discriminatedUnion("status", [
z.object({
status: z.literal("success"),
data: z.string(),
}),
z.object({
status: z.literal("error"),
error: z.instanceof(Error),
}),
]);
// 验证成功的情况
result.parse({
status: "success",
data: "成功了!",
}); // 通过
// 验证错误的情况
result.parse({
status: "error",
error: new Error("出错了"),
}); // 通过
访问联合选项
你可以使用 .options
属性获取联合类型的所有选项:
ts
const myUnion = z.discriminatedUnion("status", [
z.object({ status: z.literal("loading") }),
z.object({ status: z.literal("success") }),
z.object({ status: z.literal("error") }),
]);
console.log(myUnion.options); // 获取所有选项
合并判别联合类型
要合并两个或更多判别联合类型,可以展开它们的 .options
:
ts
const A = z.discriminatedUnion("status", [
z.object({ status: z.literal("loading") }),
z.object({ status: z.literal("success") }),
]);
const B = z.discriminatedUnion("status", [
z.object({ status: z.literal("error") }),
z.object({ status: z.literal("timeout") }),
]);
const Combined = z.discriminatedUnion("status", [
...A.options,
...B.options,
]);
错误处理
对于判别联合类型,Zod 会根据判别字段的值来确定使用哪个模式进行验证,这样可以提供更精确的错误信息:
ts
const result = z.discriminatedUnion("status", [
z.object({
status: z.literal("success"),
data: z.string(),
}),
z.object({
status: z.literal("error"),
message: z.string(),
}),
]);
// 当提供了错误的字段时
result.parse({
status: "success",
message: "这不应该在这里", // 错误:success 状态应该有 data 字段
}); // 将抛出特定的错误