我将 Prisma 与 TRPC 和 TypeScript 结合使用,在尝试在查询中包含相关模型时遇到 TypeScript 警告。即使查询正确运行并返回预期数据,VSCode 也会给出以下错误:
Property 'posts' does not exist on type 'User'
这是我的代码的简化版本:
const includeFields = {
posts: true,
};
type UserWithPosts = Prisma.UserGetPayload<{ include: typeof includeFields }>;
const { data, isLoading } = trpc.user.findMany.useQuery<UserWithPosts[]>(
{ include: includeFields },
{}
);
if (!isLoading && data) {
const firstUser = data[0];
if (firstUser) {
console.log(firstUser.posts); // <-- I'm getting a warning here
}
}
这是我的 Prisma 架构的相关部分,定义
User
和 Post
之间的关系:
model User {
id String @id @default(cuid())
name String
posts Post[] // Relation to the Post model
}
model Post {
id String @id @default(cuid())
title String
userId String
user User @relation(fields: [userId], references: [id])
}
我尝试直接在
useQuery
调用中内联包含对象,但这没有帮助。
我期望 TypeScript 根据传递给 Prisma 的 include 对象推断出帖子存在于
UserWithPosts
类型上。由于我在查询中包含 posts
关系,我认为 TypeScript 会识别出 posts
在结果数据中可用。然而,尽管查询返回了正确的数据(包含 posts
),TypeScript 仍然会发出警告,指出 User 对象上不存在帖子。
类型:
const includeFields = {
posts: true,
};
是:
{ posts: boolean }
这意味着:
type UserWithPosts = Prisma.UserGetPayload<{ include: typeof includeFields }>;
真的是这样吗:
type UserWithPosts = Prisma.UserGetPayload<{ include: { posts: boolean } }>;
这里的
boolean
可能是true
或false
。如果 true
该字段将被包含,如果 false
则不会。因此,在类型级别,不能保证该属性存在。
最简单的修复方法是这样的:
const includeFields = {
posts: true,
} as const;
这告诉打字稿将对象的所有属性推断为常量,这意味着它可以采用
true
而不是 boolean
的类型。现在它不能再是 false
并且正确的类型应该传播。