input using z.or not working properly
i have an input like this
let input = z.object({
name: z.string().optional()
}).or(z.object({
id: z.number().optional()
}));
when I call the route with { name: "123" } I get in the input { name: "123" } properly like I should,
but when I call the same route with { id: 2 } then I get in the input {} - the rawInput is correctly { id: 2 } but
the data is not transferred to input, when I switch the order of the input like this
let input = z.object({
id: z.number().optional()
}).or(z.object({
name: z.string().optional()
}));
then now, id is the one that works and name gives {}
this is probably a bug, should I post this in the git or maybe it wasn't supposed to work at all?
5 Replies
Think about how it works internally, both properties are optional. It will try to parse each possible type in order, and take the first success as the result.
So in both examples, it parses, sees the optional type isn’t there which is fine, and returns the empty result
This isn’t exactly a Zod help channel though, you’re best to refer to their own docs and issues for suggestions on workarounds
I think there’s an option to make an input with extraneous inputs throw and maybe switching that on will force the wrong type to come up invalid and try the next one
@Barakonda does it work if you remove the optional() calls?
@msalsbery ill check and get back to you soon
@Nick Lucas true, but it works if its a sub object inside the main input schema(from another part in my project)
like this
let input = z.object({
name: z.object({z.string().optional()
}).or(z.object({
id: z.number().optional()
}));
@msalsbery yes' removing the optional works... pretty weird
Your example is incomplete by the way, but I’d guess there’s some non-optional part of the that structure which does match fine
You might want a discriminatedUnion
Cool, like @Nick Lucas mentioned, if you think about how it works, with the optional, if the property isn’t there you get the “else” which is {} … the other object definition in the union isn’t looked at