Advanced type safety

The generated code for Prisma Client contains several helpful types and utilities that you can use to make your application more type-safe. This page describes patterns for leveraging them.

Using the Prisma namespace

The Prisma namespace can be imported and various utilities accessed using dot notation. Generated types are one such utility. The following example shows how to import the Prisma namespace and use it to access a generated type. This type is then used to create a typed select statement which can be used when composing queries.

import { Prisma } from '@prisma/client'
const userEmail: Prisma.UserSelect = {
email: true,

What are generated types?

Generated types are TypeScript types that are derived from your models. They allow you to perform operations such as a select or include on your records in a typed manner.

UserSelect is one such generated type. Its object properties match those that are supported by select statements according to the model.

The first tab below shows the UserSelect generated type and how each property on the object has a type annotation. The second tab shows the resulting schema model.

Generated type
type Prisma.UserSelect = {
id?: boolean | undefined;
email?: boolean | undefined;
name?: boolean | undefined;
posts?: boolean | Prisma.PostFindManyArgs | undefined;
profile?: boolean | Prisma.ProfileArgs | undefined;

In TypeScript the concept of type annotations is when you declare a variable and add a type annotation to describe the type of the variable. See the below example.

const myAge: number = 37
const myName: string = 'Rich'

Both of these variable declarations have been given a type annotation to specify what primitive type they are, number and string respectively. Most of the time this kind of annotation is not needed as TypeScript will infer the type of the variable based on how its initialized. In the above example myAge was initialized with a number so TypeScript guesses that it should be typed as a number.

Going back to the UserSelect type, if you were to use dot notation on the created object userEmail, you would have access to all of the fields on the User model that can be interacted with using a select statement.

1model User {
2 id Int @id @default(autoincrement())
3 email String @unique
4 name String?
5 posts Post[]
6 profile Profile?
import { Prisma } from '@prisma/client'
const userEmail: Prisma.UserSelect = {
email: true,
// properties available on the typed object

In the same mould, you can type an object with an include generated type then your object would have access to those properties on which you can use an include statement.

import { Prisma } from '@prisma/client'
const userPosts: Prisma.UserInclude = {
posts: true,
// properties available on the typed object

See the model query options reference for more information about the different types available.

Edit this page on GitHub