Z
Zod11mo ago
Gludek

Merge on a wrapped object schema

Hey how can I merge/intersect zod object with discriminated union so I have .extend later available? Main type is like this
z.object({
someData
}).and(z.discriminatedUnion("type",[
z.object(
{
type:0
otherField: z.string()
}
),
z.object(
{
type:1
otherField: z.string().nullish
}
)
]))
z.object({
someData
}).and(z.discriminatedUnion("type",[
z.object(
{
type:0
otherField: z.string()
}
),
z.object(
{
type:1
otherField: z.string().nullish
}
)
]))
3 Replies
Scott Trinh
Scott Trinh11mo ago
Unfortunately not. There are strategies to make that a bit easier, but the best direction I can give you is that you'll need to extend the base z.object schema and add the intersections in multiple places to get the right type. You can hide all of this mess within a module to at least keep the public-facing API cleaner for consumers, but all of the downstream consumers will get wrapped types, not a base ZodObject...
Gludek
Gludek11mo ago
oh well, I wanted to do that to have a bit easier time sincly only 1 type of 3 has this other field, but I'll just set it to nullish and check for it @Scott Trinh do you think it would be possible for you to add merge,and or extend onto union/discriminatedUnion. So type like
const typeSchema = z.discriminatedUnion("type",[
z.object(
{
type:0
otherField: z.string()
}
),
z.object(
{
type:1
otherField: z.string().nullish
}
)
]).merge(z.object(field: z.string()))
const typeSchema = z.discriminatedUnion("type",[
z.object(
{
type:0
otherField: z.string()
}
),
z.object(
{
type:1
otherField: z.string().nullish
}
)
]).merge(z.object(field: z.string()))
would result in
type TType = z.infer<typeof typeSchema>
// type TType =
// | {
// type:0
// otherField: string
// field: string
// }
// | {
// type:1
// otherField?: string | null
// field: string
// }
type TType = z.infer<typeof typeSchema>
// type TType =
// | {
// type:0
// otherField: string
// field: string
// }
// | {
// type:1
// otherField?: string | null
// field: string
// }
Scott Trinh
Scott Trinh11mo ago
Well, not really. union can be any type z.union([z.string(), z.number()]) for instance, and discriminated union is in a bit of a holding pattern while we rethink how it works at all. and should work though, I think?