typescript 如何为Prisma select属性键入变量

smtd7mpg  于 2022-12-05  发布在  TypeScript
关注(0)|答案(3)|浏览(153)

我正在寻找一种方法来定义Prisma select语句,然后在多个地方使用它。例如:

const userSelect: Prisma.UserSelect = {
    id: true,
    name: true,
}

const user = await prisma.user.findUnique({
    where: { id: 1 },
    select: userSelect
})

const posts = await prisma.post.findMany({
    where: { authorId: 1 },
    select: {
        id: true,
        user: {
            select: userSelect
        }
    }
})

但是,这并不能正常工作。当在查询中使用userSelect时,查询知道userSelect是预期的类型Prisma.UserSelect,但它们不知道实际上选择了哪些字段。这最终导致userposts.user都被键入为{}
另一种方法是将userSelect写成如下形式:

const userSelect = {
    id: true,
    name: true,
} as const;

这在查询中起作用,并正确地键入查询结果。然而,现在我在userSelect的定义中失去了类型安全和自动完成功能。
有人能想出一个解决方案,它能在查询select属性、查询结果中正常工作,并且还能在select对象的定义中允许类型安全吗?

k4emjkb1

k4emjkb11#

Prisma刚刚发布了一篇涵盖这一确切主题的文章。https://www.prisma.io/blog/satisfies-operator-ur8ys8ccq7zb
引用文章:
Prisma中的satisfes操作符最常见的用例之一是推断特定查询方法(如findUnique)的返回类型-仅包括模型及其关系的选定字段。

import { Prisma } from "@prisma/client";

// Create a strongly typed `PostSelect` object with `satisfies`
const postSelect = {
  title: true,
  createdAt: true,
  author: {
    name: true,
    email: true,
  },
} satisfies Prisma.PostSelect;

// Infer the resulting payload type
type MyPostPayload = Prisma.PostGetPayload<{ select: typeof postSelect }>;

// The result type is equivalent to `MyPostPayload | null`
const post = await prisma.post.findUnique({
  where: { id: 3 },
  select: postSelect,
});
jutyujz0

jutyujz02#

在TS 4.9+中,您可以使用satisfies来执行以下操作:

const userSelect = { ... } satisfies Prisma.UserSelect;

这会保留userSelect的类型,同时仍会检查并自动完成括号内的内容。
TS4.8中这个问题的标准解决方案是使用一个通用的helper函数:

function makeUserSelect<T extends Prisma.UserSelect>(t: T): T { return t; }

const userSelect = makeUserSelect({ ... });
pcrecxhr

pcrecxhr3#

第一个
应正确键入,您可以在必要时使用UserSelect类型。

相关问题