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 GitHub Comments
I’m actually not against bringing some (all?) of ZodObject’s methods to
ZodDiscriminatedUnion
since 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.