You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Prisma与TRPC时TypeScript无法识别关联字段的问题

Prisma + TRPC + TypeScript 关联查询类型推断异常问题

问题现象

使用Prisma、TRPC和TypeScript开发时,查询包含关联模型的用户数据,接口能正常返回预期结果,但VSCode抛出TypeScript警告:

Property 'posts' does not exist on type '{ id: string; id: string; }'.

客户端代码

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); // 此处出现警告
  }
}

Prisma Schema定义

model User {
  id    String  @id @default(cuid())
  name  String
  posts Post[]  // 关联Post模型
}

model Post {
  id     String @id @default(cuid())
  title  String
  userId String
  user   User   @relation(fields: [userId], references: [id])
}

TRPC服务端路由定义

export const usersRouter = t.router({
  findMany: t.procedure.input(UserFindManySchema).query(async ({ ctx, input }) => {
    return await ctx.prisma.user.findMany(input);
  })
});

预期结果

TypeScript能根据传入Prisma的include参数,自动推断返回的用户对象包含posts字段,消除类型警告。

已尝试方案

  • 将include对象直接内联到useQuery调用中
  • 给includeFields添加as const标记

关键发现

服务端直接调用prisma.user.findMany({ include: { posts: true } })时,TypeScript能正确推断返回类型;但通过TRPC路由调用时,类型信息丢失,导致客户端无法识别posts字段。

解决方案

问题核心是TRPC路由未正确传递Prisma的类型信息,需调整路由的输入Schema和类型推断逻辑:

1. 修正输入Schema定义

确保UserFindManySchema与Prisma的UserFindManyArgs类型对齐,让TRPC能识别include参数的结构:

import { z } from "zod";
import type { Prisma } from "@prisma/client";

// 定义与Prisma UserFindManyArgs对齐的Zod Schema
const UserFindManySchema = z.object({
  include: z.object({
    posts: z.boolean().optional(),
  }).optional(),
  // 可按需添加其他findMany支持的参数(如where、select等)
}) satisfies z.ZodType<Prisma.UserFindManyArgs>;

2. 让TRPC自动推断返回类型

无需手动指定路由的返回类型,TRPC会根据prisma.user.findMany(input)的返回值自动推断类型:

export const usersRouter = t.router({
  findMany: t.procedure.input(UserFindManySchema).query(async ({ ctx, input }) => {
    return ctx.prisma.user.findMany(input);
  }),
});

3. 客户端简化调用(可选)

客户端无需手动指定useQuery的泛型,TRPC会根据传入的include参数自动推断返回数据类型:

const includeFields = { posts: true } as const;

const { data, isLoading } = trpc.user.findMany.useQuery({ include: includeFields });

if (!isLoading && data) {
  console.log(data[0]?.posts); // 类型推断正常,无警告
}

内容的提问来源于stack exchange,提问作者Svante Grundström

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:43:13