Generated typings for optional values differ from the definition of Prisma client typings
nikolasburk opened this issue · 1 comments
When using the Prisma client together with graphqlgen
in TS scrict mode, the generated typings for optional fields from the Prisma datamodel and the graphqlgen
resolver arguments don't match. Example:
datamodel.prisma
type User {
id: ID! @unique
email: String! @unique
name: String
posts: [Post!]!
}
type Post {
id: ID! @unique
createdAt: DateTime!
updatedAt: DateTime!
published: Boolean! @default(value: "false")
title: String!
content: String
author: User!
}
For example, content
on Post
is optional here. Now consider this GraphQL schema:
scalar DateTime
type Query {
feed: [Post!]!
filterPosts(searchString: String): [Post!]!
post(id: ID!): Post
}
type Mutation {
signupUser(email: String!, name: String): User!
createDraft(title: String!, content: String, authorEmail: String!): Post!
deletePost(id: ID!): Post
publish(id: ID!): Post
}
type Post {
id: ID!
createdAt: DateTime!
updatedAt: DateTime!
published: Boolean!
title: String!
content: String
author: User!
}
type User {
id: ID!
email: String!
name: String
posts: [Post!]!
}
The content
field is optional in the createDraft
mutation. Now, the generated resolver args from graphqlgen
for the input to createDraft
look like this:
export interface ArgsCreateDraft {
title: string
content: string | null
}
On the other hand, the generated PostCreateInput
type for the createPost
operation in the Prisma client API looks as follows:
export interface PostCreateInput {
published?: Boolean;
title: String;
content?: String;
author: UserCreateOneWithoutPostsInput;
}
content
here is declared as an optional instead of string | null
. As fas as I understand, the optional is interpreted as string | undefined
. Now, when implementing the createDraft
resolver like so:
createDraft: (parent, { title, content, authorEmail }, ctx) => {
return ctx.prisma.createPost({
title,
content,
author: {
connect: {
email: authorEmail,
},
},
})
},
TypeScript throws this error in strict mode:
src/resolvers/Mutation.ts:15:7 - error TS2322: Type 'string | null' is not assignable to type 'string | undefined'.
Type 'null' is not assignable to type 'string | undefined'.
15 content,
~~~~~~~
src/generated/prisma-client/index.ts:282:3
282 content?: String;
~~~~~~~
The expected type comes from property 'content' which is declared here on type 'PostCreateInput'
src/resolvers/Query.ts:14:29 - error TS2345: Argument of type '{ where: { OR: ({ title_contains: string | null; } | { content_contains: string | null; })[]; }; }' is not assignable to parameter of type '{ where?: PostWhereInput | undefined; orderBy?: "id_ASC" | "id_DESC" | "createdAt_ASC" | "createdAt_DESC" |"updatedAt_ASC" | "updatedAt_DESC" | "published_ASC" | "published_DESC" | ... 4 more ... | undefined; ... 4 more ...; last?: number | undefined; }'.
Types of property 'where' are incompatible.
Type '{ OR: ({ title_contains: string | null; } | { content_contains: string | null; })[]; }' is not assignable to type 'PostWhereInput'.
Types of property 'OR' are incompatible.
Type '({ title_contains: string | null; } | { content_contains: string | null; })[]' is not assignable to type 'PostWhereInput | PostWhereInput[] | undefined'.
Type '({ title_contains: string | null; } | { content_contains: string | null; })[]' is not assignable to type 'PostWhereInput[]'.
Type '{ title_contains: string | null; } | { content_contains: string | null; }' is not assignable to type 'PostWhereInput'.
Type '{ title_contains: string | null; }' is not assignable to type 'PostWhereInput'.
Types of property 'title_contains' are incompatible.
Type 'string | null' is not assignable to type 'string | undefined'.
Type 'null' is not assignable to type 'string | undefined'.
14 return ctx.prisma.posts({
~
15 where: {
~~~~~~~~~~~~~~
...
24 },
~~~~~~~~
25 })
~~~~~