Skip to main content

Computed fields

Computed fields allow you to derive a new field based on existing data. A common example is when you want to compute a full name. In your database, you may only store the first and last name, but you can define a function that computes a full name by combining the first and last name. Computed fields are read-only and stored in your application's memory, not in your database.

Using a Prisma Client extension

The following example illustrates how to create a Prisma Client extension that adds a fullName computed field at runtime to the User model in a Prisma schema.

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient().$extends({
result: {
user: {
fullName: {
needs: { firstName: true, lastName: true },
compute(user) {
return `${user.firstName} ${user.lastName}`
},
},
},
},
})

async function main() {
/**
* Example query containing the `fullName` computed field in the response
*/
const user = await prisma.user.findFirst()
}

main()
Show CLI results

The computed fields are type-safe and can return anything from a concatenated value to complex objects or functions that can act as an instance method for your models.

Instructions prior to Prisma ORM 4.16.0
warning

With Prisma Client extensions Generally Available as of Prisma ORM version 4.16.0, the following steps are not recommended. Please use a client extension to accomplish this.

Prisma Client does not yet natively support computed fields, but, you can define a function that accepts a generic type as an input then extend that generic to ensure it conforms to a specific structure. Finally, you can return that generic with additional computed fields. Let's see how that might look:

// Define a type that needs a first and last name
type FirstLastName = {
firstName: string
lastName: string
}

// Extend the T generic with the fullName attribute
type WithFullName<T> = T & {
fullName: string
}

// Take objects that satisfy FirstLastName and computes a full name
function computeFullName<User extends FirstLastName>(
user: User
): WithFullName<User> {
return {
...user,
fullName: user.firstName + ' ' + user.lastName,
}
}

async function main() {
const user = await prisma.user.findUnique({ where: 1 })
const userWithFullName = computeFullName(user)
}

In the TypeScript example above, a User generic has been defined that extends the FirstLastName type. This means that whatever you pass into computeFullName must contain firstName and lastName keys.

A WithFullName<User> return type has also been defined, which takes whatever User is and tacks on a fullName string attribute.

With this function, any object that contains firstName and lastName keys can compute a fullName. Pretty neat, right?

Going further

  • Learn how you can use Prisma Client extensions to add a computed field to your schema — example.
  • Learn how you can move the computeFullName function into a custom model.
  • There's an open feature request to add native support to Prisma Client. If you'd like to see that happen, make sure to upvote that issue and share your use case!