Zod DiscriminatedUnion type.
Zod plans to deprecate the very useful DiscriminatedUnion
type and will not continue improving it with some much-needed enhancements. We will.
$ npm install zod.discriminatedunion
zod.discriminatedunion
requires zod
as a peer dependency.
$ npm install zod
A discriminated union is a union of object schemas and or other discriminated union schemas that all share a particular key.
type MyUnion =
| { status: "success"; data: string }
| { status: "failed"; error: Error };
Such unions can be represented with the z.discriminatedUnion
method. This enables faster evaluation, because the discriminator key (status
in the example above) can be checked to determine which schema should be used to parse the input. This makes parsing more efficient and lets Zod report friendlier errors.
With the basic union method the input is tested against each of the provided "options", and in the case of invalidity, issues for all the "options" are shown in the zod error. On the other hand, the discriminated union allows for selecting just one of the "options", testing against it, and showing only the issues related to this "option".
const myUnion = y.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.string() }),
z.object({ status: z.literal("failed"), error: z.instanceof(Error) }),
]);
myUnion.parse({ status: "success", data: "yippie ki yay" });
These methods apply schema alterations to all the "options", similar to the methods on the Objects schema, but they do not effect the discriminator.
const myUnion = y.discriminatedUnion("status", [
z.object({ status: z.literal("success"), data: z.string() }),
z.object({ status: z.literal("failed"), error: z.instanceof(Error) }),
]);
const strictSchema = myUnion.strict();
const stripSchema = myUnion.strip();
const pasthroughSchema = myUnion.pasthrough();
const catchallSchema = myUnion.catchall(z.number());
const pickSchema = myUnion.pick({ data: true }); // discriminator is allways picked
const omitSchema = myUnion.omit({ error: true }); // discriminator cannot be omitted
const deepPartialSchema = myUnion.deepPartial(); // discriminator is still required
const partialSchema = myUnion.partial(); // discriminator is still required
const partialWithMaskSchema = myUnion.partial({ error: true }); // discriminator cannot be made optional
const requiredSchema = myUnion.required();
const requiredWithMaskSchema = myUnion.required({ data: true });
- Object schema functions
- DiscriminatedUnion as option for a discriminatedUnion
- Baseline, similar to
z.discriminatedUnion
in Zod version 3.21.4