question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support multiple discriminated unions on same object

See original GitHub issue

First of all, thank you for Zod! I’m just starting to use it on a new project. I have a case come up quite frequently that I don’t know how to resolve using current Zod functionality. I’ve asked a similar question here and haven’t received a response, so I’m logging an issue considering functionality may need to be added to Zod.

I believe I want multiple discriminated unions on the same object. Here’s some code that illustrates what I’m trying to accomplish:

const schema = z.object({
    sku: z.string()
  }).merge(z.discriminatedUnion("product", [
    z.object({
      product: z.literal("shoes"),
      price: z.number(),
      material: z.union([z.literal("leather"), z.literal("suede")])
    }),
    z.object({
      product: z.literal("shirt"),
      price: z.string()
    })
 ]).merge(z.discriminatedUnion("color", [
    z.object({
       color: z.literal("red"),
       size: z.enum(["s", "m"])
    }),
    z.object({
      color: z.literal("blue"),
      size: z.enum(["m", "l"])
    })
  ]);

In other words, the object will (1) always have a sku, (2) always have product and price (and sometime material), and (3) always have color and size. The combinations would be restricted by the discriminated unions.

This doesn’t work, though, because ZodDiscriminatedUnion doesn’t have a merge property and ZodDiscriminatedUnion can’t be merged into ZodObject.

I’m not particular about the implementation, so long as it’s simple (it’s a common use case) and preferably does not require refine or superRefine (though I’d still like to understand how solve it with refine or superRefine in the meantime). Thanks!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:7
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
scotttrinhcommented, Mar 15, 2022

I’m actually not against bringing some (all?) of ZodObject’s methods to ZodDiscriminatedUnion since it is in some senses a subtype, but I’m not sure what the level of effort there is off the top of my head. Would be a nice thing for someone to investigate!

1reaction
Aaroniuscommented, Jul 6, 2022

I can’t or I would. I don’t have the necessary rights.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handbook - Unions and Intersection Types - TypeScript
Discriminating Unions​​ A common technique for working with unions is to have a single field which uses literal types which you can use...
Read more >
Object with multiple fields of the same generic union type
In TypeScript, discriminated unions are union types with a discriminant property; each member of the union must have a property with the ...
Read more >
The case for Discriminated Union Types with Typescript
Why Discriminated Union Types are an important part of modeling solutions with TypeScript.
Read more >
Discriminated Unions - F# | Microsoft Learn
Discriminated unions provide support for values that can be one of a number of named cases, possibly each with different values and types....
Read more >
Discriminated Unions - Multiple Fields, SubClassing ... - GitHub
When there are multiple common fields between interfaces the Discriminated Unions is not able to determine which field is to be the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found