Reputation: 663
This is my first ever TypeScript project and I am using Fastify and Prisma to build it. I have extensively searched for this error and it's not a generic one. Similar questions were not helpful to my case. I am working on a User table where I have the prisma.schema as:
model User {
id Int @id @default(autoincrement())
firstName String
lastName String
email String @unique
phone String @unique
room Room? @relation(fields: [roomId], references: [id])
roomId Int?
utilities Utility[]
rentStatus Boolean?
amountDue Float?
dateSigned DateTime?
dateLeft DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
I have a user.schema.ts that contains the Zod schema for validation:
import { z } from 'zod'
const createUserSchema = z.object({
firstName: z.string({
required_error: "First name is required"
}),
lastName: z.string({
required_error: "Last name is required"
}),
email: z.string({
required_error: "Email is required",
invalid_type_error: "Email must be a string"
}).email(),
phone: z.string({
required_error: "Phone number is required"
})
});
export type CreateUserInput = z.infer<typeof createUserSchema>
In my user.service.ts I have this setup:
import prisma from "../utils/prisma";
import { CreateUserInput } from "./user.schema";
export async function createUser(input: CreateUserInput) {
const user = await prisma.user.create({
data: input
});
}
But "data" is errored out with this:
(property) data: (Prisma.Without<Prisma.UserCreateInput, Prisma.UserUncheckedCreateInput> & Prisma.UserUncheckedCreateInput) | (Prisma.Without<Prisma.UserUncheckedCreateInput, Prisma.UserCreateInput> & Prisma.UserCreateInput)
The data needed to create a User.
Type '{ firstName?: string; lastName?: string; email?: string; phone?: string; }' is not assignable to type '(Without<UserCreateInput, UserUncheckedCreateInput> & UserUncheckedCreateInput) | (Without<...> & UserCreateInput)'.
Type '{ firstName?: string; lastName?: string; email?: string; phone?: string; }' is not assignable to type 'Without<UserUncheckedCreateInput, UserCreateInput> & UserCreateInput'.
Type '{ firstName?: string; lastName?: string; email?: string; phone?: string; }' is not assignable to type 'UserCreateInput'.
Property 'firstName' is optional in type '{ firstName?: string; lastName?: string; email?: string; phone?: string; }' but required in type 'UserCreateInput'.ts(2322)
index.d.ts(1911, 5): The expected type comes from property 'data' which is declared here on type '{ select?: UserSelect; include?: UserInclude; data: (Without<UserCreateInput,UserUncheckedCreateInput> & UserUncheckedCreateInput) | (Without<...> & UserCreateInput); }'
Unfortunately, I cannot make sense of this error. One thing that stands out though is it complaining about firstName, lastName, email and phone being optional. But I have set it as required both in Zod and Prisma. It seems like I am missing something very trivial here.
Upvotes: 0
Views: 4522
Reputation: 663
Thanks to @Shea I was able to narrow down the issue. Looks like Zod was creating optional fields for firstName, lastName, email and phone, even though I did not have them set to optional. The fix was adding "strict": true
in tsconfig.json
under "compilerOptions"
.
Upvotes: 2
Reputation: 3218
Whatever your user.schema
file is, it is emitting a type CreateUserInput
which lists all the properties of a User
as optional. That is incompatible with Prisma's expected type for await prisma.user.create
which expects some fields which are required. Because you are passing in input
which has type CreateUserInput
, Prisma thinks all those fields are optional. Your error lies in why CreateUserInput
has its fields listed as optional, which seems to be something to do with z.infer
Upvotes: 1