📐

PrismaでTypeScriptの型を自在に操る!Prisma.validatorの活用

2024/11/08に公開

はじめに

Prismaで取得してきたオブジェクトがTypeScriptの型でバリバリコード補完が効いて「すごい!」と思った人は少なくないはずです。

ただし、取得してきたそのオブジェクトの型を他で使おうとしたときに「ん?これどうやって定義したら良いんだ?」と思った人も少なくないはず...。

https://youtu.be/gQ77Q5_-o_4?si=ni2UrDProw-Y0naI

ということでそんな悩みがある人のためにPrisma.validatorを紹介したいと思います。

前提

まず、以下のようなテーブル構成だったとします。

  • UserはProfileと1:1の関係
  • UserはPostとは1:多の関係

Prismaのスキーマは以下になります。

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  title     String   @db.VarChar(255)
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

model Profile {
  id     Int     @id @default(autoincrement())
  bio    String?
  user   User    @relation(fields: [userId], references: [id])
  userId Int     @unique
}

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
  articles   Post[]
  additionalData Profile?
}

課題

動画はこちら

例えばユーザーの情報をとってこようと思うと簡単にとってこれるし、コードの補完も効きます。これがPrismaの超便利な機能ですよね。

ただし、とってきたオブジェクトの型をどこか別の場所で使おう(例えば関数のパラメータとして渡したい)とすると、途端に悩ましくなります。

作るのも大変ですし、保守していくのも大変です。

Prisma.validatorを使おう!

動画はこちら

そこで使えるのがPrisma.validatorです。

https://www.prisma.io/docs/orm/prisma-client/type-safety/prisma-validator

Prisma.validatorで、どのようにDBの情報をとってくるか宣言します。要は find などをするときに selectinclude に書く中身です。

export const userWithRelations = Prisma.validator<Prisma.UserDefaultArgs>()({
  select: {
    id: true,
    email: true,
    name: true,
    additionalData: {
      select: { bio: true },
    },
    articles: {
      select: { title: true },
    },
  },
});

この情報をそのまま find などに渡せますし、

const user = await prisma.user.findFirstOrThrow({
  select: userWithRelations.select,
});

以下のように Prisma.XXXGetPayload を使うことで、

export type UserWithRelations = Prisma.UserGetPayload<typeof userWithRelations>;

find などを使ったときに取得できるオブジェクトの型も生成できます!

selectinclude を他でも使えるのはもちろんのこと、取得したオブジェクトの形も他で使えるので、とても便利です。

まとめ

  • Prismaで取得したオブジェクトの型は自作しない方が良い(保守が大変)
  • 取得したオブジェクトの型が明示的に必要な場合はPrisma.validatorを活用する

ということで、少しでもPrismaを快適に使えるようになったらと思います 🚀

Discussion