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 union doesn't work with transform #1171

Closed
lobotomoe opened this issue May 27, 2022 · 7 comments · Fixed by #1290
Closed

Discriminated union doesn't work with transform #1171

lobotomoe opened this issue May 27, 2022 · 7 comments · Fixed by #1290

Comments

@lobotomoe
Copy link

lobotomoe commented May 27, 2022

Possibly it is not bug. Any way to "post"-define discriminator (define in transform)?

Codesandbox example 1
Codesandbox example 2

Example 1:

import z from "zod";

const schemaA = z
  .object({
    mo: z.number().optional(),
    aa: z.number()
  })
  .transform((content) => ({
    ...content,
    k: "kindA" as const
  }));

const schemaB = z
  .object({
    mi: z.number().optional(),
    aao: z.number()
  })
  .transform((content) => ({
    ...content,
    k: "kindB" as const
  }));

const schemaC = z.discriminatedUnion("k", [schemaA, schemaB]);

Example 2:

import z from "zod";

const schemaA = z.object({
  T: z.literal("error"),
  c: z.number(),
  m: z.string()
});

const schemaB = z
  .object({
    T: z.literal("ss"),
    mi: z.number().optional(),
    aao: z.number()
  })
  .transform((content) => ({
    ...content,
    someField: "someValue" as const
  }));

const schemaC = z.discriminatedUnion("T", [schemaA, schemaB]);

Error: The discriminator value could not be extracted from all the provided schemas

@oliverbutler
Copy link

Same issue here, love this operator, but I need to rename keys before the discriminatedUnion

@danielo515
Copy link

Does anyone know any workaround? This makes adding certain optional types based on other fields impossible, forcing you to always provide those

@roblabat
Copy link
Contributor

I made a pull request to address this issue as I have the same problem.

Waiting for merge or feedback

@dagda1
Copy link

dagda1 commented Aug 17, 2022

I'm hitting this too, would love to see @roblabat's PR make it through

roblabat added a commit to roblabat/zod that referenced this issue Sep 6, 2022
@jeremyisatrecharm
Copy link

I'm also hitting this.

colinhacks pushed a commit that referenced this issue Nov 15, 2022
…natedUnion (#1290)

* #1171

* fix tests

* add superRefine in tests

* add support for lazy

* fix typings

* fixe typings for asserted lazy

* fix

* clean console.log from debug

* Clean up discriminatedUnion

* Fix deno test

Co-authored-by: Colin McDonnell <[email protected]>
@davidtorosyan
Copy link

I see the fix is now available in v3.20.0-beta, but when I upgraded and tried the first example I got this error:

Type 'ZodEffects<ZodObject<{ mo: ZodOptional<ZodNumber>; aa: ZodNumber; }, "strip", ZodTypeAny, { mo?: number | undefined; aa: number; }, { mo?: number | undefined; aa: number; }>, { ...; }, { ...; }>' is missing the following properties from type 'ZodObject<{ k: ZodTypeAny; } & ZodRawShape, any, any, { [x: string]: any; }, { [x: string]: any; }>': _cached, _getCached, shape, strict, and 14 more.ts(2740)

Am I doing something wrong?

@guilhermedelyra
Copy link

I see the fix is now available in v3.20.0-beta, but when I upgraded and tried the first example I got this error:

Type 'ZodEffects<ZodObject<{ mo: ZodOptional<ZodNumber>; aa: ZodNumber; }, "strip", ZodTypeAny, { mo?: number | undefined; aa: number; }, { mo?: number | undefined; aa: number; }>, { ...; }, { ...; }>' is missing the following properties from type 'ZodObject<{ k: ZodTypeAny; } & ZodRawShape, any, any, { [x: string]: any; }, { [x: string]: any; }>': _cached, _getCached, shape, strict, and 14 more.ts(2740)

Am I doing something wrong?

same here, using the newest version (3.21.4)

export const BaseRegistryTag = z
  .object({
    id: z.optional(z.string()),
    name: z.string(),
    description: z.optional(z.string()),
  })
  .strict();

const positiveNumber = z.number().positive().finite()

const hasLengthType = z.object({
  minLength: positiveNumber,
  maxLength: positiveNumber
}).refine((data) => data.maxLength >= data.minLength, "maxLength should be greater than or equal to minLength.")

export const NumberTag = BaseRegistryTag.extend({
  type: z.literal('number'),
  precision: z.optional(positiveNumber),
}).and(hasLengthType)

export const TextTag = BaseRegistryTag.extend({
  type: z.literal('text'),
}).and(hasLengthType)

export const RegistryTag = z.discriminatedUnion('type', [NumberTag, TextTag])

gives:

Type 'ZodIntersection<ZodObject<{ id: ZodOptional; name: ZodString; description: ZodOptional; type: ZodLiteral<"number">; precision: ZodOptional<...>; }, "strict", ZodTypeAny, { ...; }, { ...; }>, ZodEffects<...>>' is missing the following properties from type 'ZodObject<{ type: ZodTypeAny; } & ZodRawShape, UnknownKeysParam, ZodTypeAny, { [x: string]: any; type?: any; }, { [x: string]: any; type?: any; }>': _cached, _getCached, shape, strict, and 14 more.ts(2740)

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

Successfully merging a pull request may close this issue.

8 participants