The good thing about using Prisma is that typesafety is super siple to apply.
Let's go with an example, that I have a user model like the following:
model User {
id String @id @default(cuid())
name String
email String? @unique
emailVerified DateTime?
image String?
}
When I now query it and put it for example into a state like:
import { type User } from "@prisma/client";
const [user, setUser] = useState<User | null>(null);
return await prisma.user.findUnique({
where: {
id: userId,
}
});
Then the typing would be perfectly fine. Now the problem:
In case I do not want people to be able to query all the information given on a user, I would limit the return by setting a select like this:
return await prisma.user.findUnique({
where: {
id: userId,
},
select: {
id: true,
name: true,
}
});
The problem now. Typescript now changes the return object to something super boring like
{
id: string,
name: string,
}
So then I's need to change the state for example to this:
import { type User } from "@prisma/client";
const [user, setUser] = useState<{
id: string,
name: string,
}| null>(null);
And when you add multiple complex includes it just get super messy. Am I missing something obvious on how to limit those types on the frontend?
Cheers!
You're not returning a user. You're returning a subset of a user.
So you can make a type that matches yourself with:
Pick<User, 'name' | 'id'>
Or:
Omit<User, 'emailVerfied' | 'image' | 'passwordHash'>
And if you use that a lot you can just make your own type to import wherever you want:
// somefile.ts
import { type User } from "@prisma/client";
export type PublicUser = Pick<User, 'name' | 'id'>
// my-component.tsx
import { type PublicUser } from './somefile'
const [user, setUser] = useState<PublicUser | null>(null);