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

Prisma XOR with Zod > 3.21.1 not working #2184

Comments

@chrishoermann
Copy link

We encounterd a bug when using generated prisma types with versions greater than 3.21.1.

You can reproduce the issue in the following repo: https://github.com/chrishoermann/zod-prisma-types-bug

As you can read in the following discussion we first thought it was an issue with prisma, but after digging around and finding that the suspected type has been this way for a long time now @njdowdy found that this is a zod issue that happend somwhere in 3.21.2

Discussed in #2171

Originally posted by chrishoermann March 9, 2023
I've built a generator for prisma (zod-prisma-types) that throws a type error since prisma updated their XOR type in 4.11:

  type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };

  /**
   * XOR is needed to have a real mutually exclusive union type
   * https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types
   */
  type XOR<T, U> =
    T extends object ?
    U extends object ?
      (Without<T, U> & U) | (Without<U, T> & T)
    : U : T

before this type update the following zod schema worked without problems:

export const UserCreateInputSchema: z.ZodType<Prisma.UserCreateInput> = z.object({
  id: z.string().cuid().optional(),
  email: z.string().email({ message: "Invalid email address" }),
  name: z.string().min(1).max(100).optional().nullable(),
  role: z.union([ z.lazy(() => UserCreateroleInputSchema),z.lazy(() => RoleSchema).array() ]).optional(),
  enum: z.lazy(() => AnotherEnumSchema).optional(),
  scalarList: z.union([ z.lazy(() => UserCreatescalarListInputSchema),z.string().array() ]).optional(),
  posts: z.lazy(() => PostCreateNestedManyWithoutAuthorInputSchema).optional(),
  profile: z.lazy(() => ProfileCreateNestedOneWithoutUserInputSchema).optional(),
  location: z.lazy(() => LocationCreateNestedOneWithoutUserInputSchema).optional(),
}).strict();

export const UserUncheckedCreateInputSchema: z.ZodType<Prisma.UserUncheckedCreateInput> = z.object({
  id: z.string().cuid().optional(),
  email: z.string().email({ message: "Invalid email address" }),
  name: z.string().min(1).max(100).optional().nullable(),
  role: z.union([ z.lazy(() => UserCreateroleInputSchema),z.lazy(() => RoleSchema).array() ]).optional(),
  enum: z.lazy(() => AnotherEnumSchema).optional(),
  scalarList: z.union([ z.lazy(() => UserCreatescalarListInputSchema),z.string().array() ]).optional(),
  lat: z.number(),
  lng: z.number(),
  posts: z.lazy(() => PostUncheckedCreateNestedManyWithoutAuthorInputSchema).optional(),
  profile: z.lazy(() => ProfileUncheckedCreateNestedOneWithoutUserInputSchema).optional(),
}).strict();

export const UserCreateArgsSchema: z.ZodType<Prisma.UserCreateArgs> = z.object({
  select: UserSelectSchema.optional(),
  include: UserIncludeSchema.optional(),
  data: z.union([ UserCreateInputSchema,UserUncheckedCreateInputSchema ]),
}).strict()

so a simple union was sufficient to satisfy typescript. in Prisma 4.11 typescript now throws the following error because, as I see it, the Without<...> type can not be satisfied with a union anymore:

Type 'ZodObject<{ select: ZodOptional<ZodType<UserSelect, ZodTypeDef, UserSelect>>; include: ZodOptional<ZodType<UserInclude, ZodTypeDef, UserInclude>>; data: ZodUnion<...>; }, "strict", ZodTypeAny, { ...; }, { ...; }>' is not assignable to type 'ZodType<UserCreateArgs, ZodTypeDef, UserCreateArgs>'.
  The types of '_type.data' are incompatible between these types.
    Type '(UserCreateInput | UserUncheckedCreateInput) & (UserCreateInput | UserUncheckedCreateInput | undefined)' is not assignable to type '(Without<UserCreateInput, UserUncheckedCreateInput> & UserUncheckedCreateInput) | (Without<...> & UserCreateInput)'.
      Type 'UserCreateInput & UserUncheckedCreateInput' is not assignable to type '(Without<UserCreateInput, UserUncheckedCreateInput> & UserUncheckedCreateInput) | (Without<...> & UserCreateInput)'.
        Type 'UserCreateInput & UserUncheckedCreateInput' is not assignable to type 'Without<UserUncheckedCreateInput, UserCreateInput> & UserCreateInput'.
          Type 'UserCreateInput & UserUncheckedCreateInput' is not assignable to type 'Without<UserUncheckedCreateInput, UserCreateInput>'.
            Types of property 'lat' are incompatible.
              Type 'number' is not assignable to type 'undefined'.

I'm currently a bit stuck on how to solve this issue because I don't really know how to implement the Without<...> type especially because the z.ZodType<...> does not provide the object helper methods that would have been my first guess on how to approach this. Any help is appreciated.

@ymc9
Copy link

ymc9 commented Mar 14, 2023

Thanks for creating the issue @chrishoermann ! I'm working zenstack and hit by the same thing 😄.

@cimchd
Copy link

cimchd commented Jun 2, 2023

We have the same problem. Since almost 3 month now we are stuck to using zod in version 3.21.1.
We put a resolutions entry at the top of our monorepo:

// package.json
{
  // ...
  "resolutions": {
    "zod": "<=3.21.1",
  }
}

@ymc9
Copy link

ymc9 commented Jun 4, 2023

This issue has been here for a while 😄. Just wondering if it's on the radar for a fix soon.

@Intevel
Copy link

Intevel commented Jun 26, 2023

It seems like this bug does not occur in v4.16.1 of Prisma 👍🏼

@oceandrama
Copy link

oceandrama commented Jun 27, 2023

@Intevel No, I can confirm same error with prisma@4.16.1 and zod@3.21.4

@Intevel
Copy link

Intevel commented Jun 27, 2023

@Intevel No, I can confirm same error with prisma@14.16.1 and zod@3.21.4

Did you updated your @prisma/client aswell?

@oceandrama
Copy link

Did you updated your @prisma/client aswell?

Yes, sure

@artem-alek
Copy link

Waiting for an update as well. Stuck here too

@chrishoermann
Copy link
Author

any news on this one? Is it confirmed as a bug yet?

@ymc9
Copy link

ymc9 commented Aug 31, 2023

If it's confirmed to be a bug, I'd like to try making a fix.

@ymc9
Copy link

ymc9 commented Sep 3, 2023

Hi @colinhacks , we need some attention here 😄. Many people build Prisma-related tools using zod and all likely blocked to some extent.

@fer112233
Copy link

This issue needs to get more attention!

@aronmal
Copy link

aronmal commented Oct 7, 2023

I do agree. I sadly have switched to dirzzle for new projetcs by now.

@laneme
Copy link

laneme commented Nov 30, 2023

Zod sure has a lot of open issues for a validation library. No wonder its the most used these days.

This is probably gonna take some time to get picked up without a random dev stepping in.

@karthi-21
Copy link

Not only prisma, we recently encountered the same error with nextjs react-hook-forms zodResolver.

@ksdaylight
Copy link

Hope this problem can be solved .

@Darkbound
Copy link

Here to add some weight to the issue

@dominic-schmid
Copy link

I've got that same problem. Is there any workaround in the meantime (that isn't downgrading)?

@CasperSK89
Copy link

We need this fixed :-)

@rickylabs
Copy link

Any news on this topic ? This is a blocking issue that prevent us to generate types from Prisma schema with latest Zod release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment