zod
zod copied to clipboard
[Bug ?] Zod union ignoring zod object when fields are z.optional()
Hi,
Basically, when doing zod objects and doing an union on that, when the second object of the union has optional fields, parsing just ignore it ! Is that normal ? I can't find any information about that. I've came with a solution using discriminatedUnion but that feels a little bit dirty ...
I've created a reproduction environment for replaying the issue
https://stackblitz.com/edit/typescript-f8ppcz?file=schemas%2FschemaWithDefaultType.ts
import { z } from 'zod';
const say = console.info;
function zod_optional_union_ignored() {
// ! when one and two are optional,
const type2 = z.object({
one: z.number().optional(),
two: z.number().optional(),
});
const type1 = z.object({
three: z.number().optional(),
});
const type2or1 = z.union([type1, type2]);
const test_data = {
one: 1,
two: 2,
};
const validatedTestData = type2or1.parse(test_data);
// ! type2 is ignored, why is that ??
say('zod optional type2 object ignored', { validatedTestData });
const test_data2 = {
three: 3,
};
// type1 is parsed correctly
const validatedTestData2 = type2or1.parse(test_data2);
say('zod optional type1 object not ignored', { validatedTestData2 });
}
function zod_union_not_ignored() {
const type2 = z.object({
one: z.number(),
two: z.number(),
});
const type1 = z.object({
three: z.number(),
});
const type2or1 = z.union([type1, type2]);
const test_data = {
one: 3,
two: 2,
};
const validatedTestData = type2or1.parse(test_data);
// type2 is parsed correctly here, certainly because there is no optional
say('zod optional ingored', { validatedTestData });
}
zod_optional_union_ignored();
zod_union_not_ignored();