Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discriminated unions in Zod #1

Open
nickrttn opened this issue Feb 8, 2023 · 0 comments
Open

Discriminated unions in Zod #1

nickrttn opened this issue Feb 8, 2023 · 0 comments

Comments

@nickrttn
Copy link
Collaborator

nickrttn commented Feb 8, 2023

We would like to use Zod to define schemas for our Robots, Assembly and Template constructs, and more to come. The schemas can then be used by our customers and us to validate and type these types of data and later on by us to build editor completions and linting in our user dashboard.

In order to do that correctly, we need two features in Zod that are currently missing:

  • the usage of intersections in discriminated unions
  • the nesting of discriminated unions in discriminated unions

Both have been reported/requested by other users in the Zod repo in colinhacks/zod#1075 and colinhacks/zod#1618

In this repo, the schema that is currently breaking in particular is the robotSchema, caused by the intersections here:

types/src/robots/index.ts

Lines 180 to 183 in cecd12c

videoConcatRobotSchema,
videoEncodeRobotSchema,
videoMergeRobotSchema,
videoSubtitleRobotSchema,

These four schemas are (should be) intersections of z.object and z.discriminatedUnion. They themselves are used in the robotSchema mentioned above, which is also a z.discriminatedUnion.

A simplified example of what we want to achieve type-wise is this:

type Robots =
  | { robot: "/upload/handle" }
  | {
      robot: "/s3/store"
      use: string
      key: string
      bucket: string
    }
  | ({ robot: "/video/encode"; use: string; preset: string; result?: boolean } & (
      | { ffmpeg_stack: "v3.3.3"; preset: "foo" }
      | { ffmpeg_stack: "v4.3.1"; preset: "foo" | "bar" }
    ))

type Assembly = {
  steps: Record<string, Robots & { result?: boolean }>
}

The discriminators here are robot and ffmpeg_stack (and we might have other discriminators nested in individual Robots as well). The /video/encode robot is an intersection of an object and a discriminated union.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant