Support multiple discriminated unions on same object
See original GitHub issueFirst of all, thank you for Zod! I’m just starting to use it on a new project. I have a case come up quite frequently that I don’t know how to resolve using current Zod functionality. I’ve asked a similar question here and haven’t received a response, so I’m logging an issue considering functionality may need to be added to Zod.
I believe I want multiple discriminated unions on the same object. Here’s some code that illustrates what I’m trying to accomplish:
const schema = z.object({
sku: z.string()
}).merge(z.discriminatedUnion("product", [
z.object({
product: z.literal("shoes"),
price: z.number(),
material: z.union([z.literal("leather"), z.literal("suede")])
}),
z.object({
product: z.literal("shirt"),
price: z.string()
})
]).merge(z.discriminatedUnion("color", [
z.object({
color: z.literal("red"),
size: z.enum(["s", "m"])
}),
z.object({
color: z.literal("blue"),
size: z.enum(["m", "l"])
})
]);
In other words, the object will (1) always have a sku, (2) always have product and price (and sometime material), and (3) always have color and size. The combinations would be restricted by the discriminated unions.
This doesn’t work, though, because ZodDiscriminatedUnion doesn’t have a merge property and ZodDiscriminatedUnion can’t be merged into ZodObject.
I’m not particular about the implementation, so long as it’s simple (it’s a common use case) and preferably does not require refine or superRefine (though I’d still like to understand how solve it with refine or superRefine in the meantime). Thanks!
Issue Analytics
- State:
- Created 2 years ago
- Reactions:7
- Comments:12 (2 by maintainers)
Top Related StackOverflow Question
I’m actually not against bringing some (all?) of ZodObject’s methods to
ZodDiscriminatedUnionsince it is in some senses a subtype, but I’m not sure what the level of effort there is off the top of my head. Would be a nice thing for someone to investigate!I can’t or I would. I don’t have the necessary rights.