【问题标题】:get full type on prisma client在 prisma 客户端上获取完整类型
【发布时间】:2021-09-22 17:25:43
【问题描述】:

当我使用 prisma generate 生成我的 prisma 客户端时,我从我的数据库中获得了一个包含所有类型的 index.d.ts。 但问题是所有类型都是“单一的”并且没有关系。 当我查询类似

prisma.users.findMany({
            [... ]
            include: {
                cars: {
                  [...]
                }}});

prisma 使用正确的类型动态输入响应

users & {
        cars: cars & {
           [...]
        };
    }

所以一切正常,我有自动完成功能,除非我想将此变量传递给另一个方法,我想输入参数,所以我必须创建自己的类型用作方法参数。

type prismaUsers = users & {
        cars?: cars & {
           [...]
        };
    }

但我想问是否有办法从 prisma 中获取“完整”类型,以避免我创建所有带有可选子元素的“完整”类型,就像我为用户示例所做的那样。或者也许我做错了,还有其他方法可以做吗?

【问题讨论】:

    标签: prisma


    【解决方案1】:

    您可以最容易地使用typeof 定义相应的类型:

    myQuery = await prisma.users.findMany({
                [... ]
                include: {
                    cars: {
                      [...]
                    }}});
    type prismaUsers = typeof myQuery
    

    或者,如果您决定将查询包装在一个函数中,您可以让 TypeScript 为您推断返回类型:

    function queryUserWithCar(...) {
      return prisma.users.findMany({
                [... ]
                include: {
                    cars: {
                      [...]
                    }}});
    }
    

    然后提取函数的返回类型:

    type prismaUser = ReturnType<typeof queryUserWithCar> extends Promise<infer T> ? T : never
    

    【讨论】:

      【解决方案2】:

      您可以使用Prisma Validator API 以及一些打字稿功能来为您的查询生成类型。

      对于您提到的findMany 示例

      import { Prisma } from '@prisma/client'
      
      // 1. Define a User type that includes the "cars" relation. 
      const userWithCars = Prisma.validator<Prisma.UserArgs>()({
          include: { cars: true },
      })
      
      // 2: This type will include many users and all their cars
      type UserWithCars = Prisma.UserGetPayload<typeof userWithCars>[]
      
      

      如果您只是想自动推断包装在函数中的 prisma 查询的返回类型,可以使用PromiseReturnType。

      例如:

      import { Prisma } from '@prisma/client'
      
      async function getUsersWithCars() {
        const users = await prisma.user.findMany({ include: { cars: true } });
        return users;
      }
      
      type UsersWithCars = Prisma.PromiseReturnType<typeof getUsersWithCars>
      
      

      您可以在 Prisma 文档中的 Operating against partial structures of your model types 概念指南中阅读更多相关信息。

      【讨论】:

        【解决方案3】:

        获得“完整”类型或具有所有可能关系的模型的另一种方法(我的偏好)是使用模型类型的GetPayload 版本。该类型是一个泛型,可以接收您传递给查询的相同对象。

        import { PrismaClient, Prisma } from "@prisma/client";
        
        const prisma = new PrismaClient();
        
        type UserWithCars = Prisma.UserGetPayload<{
          include: {
            cars: true;
          }
        }>
        
        const usersWithCars = await prisma.user.findMany({
          include: {
            cars: true,
          }
        });
        

        随着您的查询变得越来越复杂,您可能希望对其进行抽象并确保它是强类型的。

        import { Prisma, PrismaClient } from "@prisma/client";
        
        const prisma = new PrismaClient();
        
        const userInclude = Prisma.validator<Prisma.UserInclude>()({
          cars: true,
        });
        
        type UserWithCars = Prisma.UserGetPayload<{
          include: typeof userInclude;
        }>;
        
        const usersWithCars = await prisma.user.findMany({
          include: userInclude,
        });
        
        

        【讨论】:

          【解决方案4】:

          最好的方法是像这样使用泛型类型:

          import { Prisma } from '@prisma/client'
          
          type UserWithMessages = Prisma.UserGetPayload<{
            include: {
              Message: {
                include: {
                  MessageParam: true;
                };
              };
            };
          }>;
          

          【讨论】:

            猜你喜欢
            • 2021-10-05
            • 2021-10-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-08
            • 1970-01-01
            • 1970-01-01
            • 2020-12-18
            相关资源
            最近更新 更多