zod: Prisma XOR with Zod > 3.21.1 not working
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 https://github.com/colinhacks/zod/discussions/2171
<div type='discussions-op-text'>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.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 74
- Comments: 23 (1 by maintainers)
Commits related to this issue
- Lock Zod version due to https://github.com/colinhacks/zod/issues/2184 — committed to ystv/badger by markspolakovs 10 months ago
- Improve addQuestionMarks, fix #2184 — committed to colinhacks/zod by colinhacks 3 months ago
- Improve `addQuestionMarks`, fix #2184 (#3352) * Improve addQuestionMarks, fix #2184 * Fix #2196 * Fix * Add test case — committed to kkpan11/zod by colinhacks 3 months ago
This issue needs to get more attention!
Hi @colinhacks , we need some attention here ๐. Many people build Prisma-related tools using zod and all likely blocked to some extent.
I do agree. I sadly have switched to dirzzle for new projetcs by now.
If itโs confirmed to be a bug, Iโd like to try making a fix.
This issue has been here for a while ๐. Just wondering if itโs on the radar for a fix soon.
This fix has landed in
zod@betaany news on this one? Is it confirmed as a bug yet?
Waiting for an update as well. Stuck here too
Not only prisma, we recently encountered the same error with nextjs react-hook-forms zodResolver.
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:
Hope this problem can be solved .
It seems like this bug does not occur in v4.16.1 of Prisma ๐๐ผ
When will the fix be released?
Here to add some weight to the issue
Thanks for creating the issue @chrishoermann ! Iโm working zenstack and hit by the same thing ๐.
@Intevel No, I can confirm same error with
prisma@4.16.1andzod@3.21.4Zod 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.
Yes, sure