Skip to content

teunmooij/zod-discriminated-union

Repository files navigation

codecov snyk npm version

zod.discriminatedunion

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.

Installation

$ npm install zod.discriminatedunion

zod.discriminatedunion requires zod as a peer dependency.

$ npm install zod

Usage

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" });

.strict/.strip/.passthrough/.catchall/.pick/.omit/.deepPartial/.partial/.required

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 });

Version history

1.0.0

  • Object schema functions

0.1.0

  • DiscriminatedUnion as option for a discriminatedUnion

0.0.1

  • Baseline, similar to z.discriminatedUnion in Zod version 3.21.4

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published