获取Prisma数据传递给React组件时的TypeScript错误排查
解决tRPC返回数据与自定义类型不匹配的TypeScript错误
问题背景
使用TypeScript、Next.js、React、tRPC和Prisma开发时,在Dashboard组件中调用tRPC的getAllUserPackets接口,获取关联了tags的Packet数据并渲染Card组件,前端显示正常,但TypeScript类型校验失败,导致部署lint检查不通过。
错误原因
自定义的Packet和Tag类型与Prisma生成的实际数据类型存在多处不匹配:
- Tag.id类型不匹配:Prisma模型中
Tag.id是String(使用cuid生成),但自定义Tag类型中id被定义为number。 - 可选字段被设为必填:Prisma模型里
card_author_name、is_org_admin、is_priority_high是可选字段(带?),但自定义Packet类型中将这些字段定义为必填的boolean/string。 - 枚举类型不匹配:
progress_indication在Prisma中是Progress枚举类型,自定义类型中被定义为通用string。 - 手动类型同步问题:手动编写类型容易和Prisma自动生成的类型脱节,导致类型不兼容。
解决方案
方案1:复用Prisma与tRPC自动生成的类型(推荐)
直接使用Prisma和tRPC自动生成的类型,避免手动维护的误差:
- 导入Prisma生成的关联类型
在需要的组件中导入Prisma的类型,并生成包含tags关联的完整Packet类型:// Card组件顶部 import type { Prisma, Tag } from '@prisma/client'; // 生成包含tags关联的Packet类型 type PacketWithTags = Prisma.PacketGetPayload<{ include: { tags: true } }>; - 更新Card组件的props类型
用自动生成的PacketWithTags替代自定义的Packet类型:const Card = (props: { packet: PacketWithTags }) => { // 组件逻辑保持不变 }; - Dashboard组件移除自定义类型导入
tRPC的useQuery返回的data已经自动推导为正确类型,无需手动导入自定义Packet:// 移除这一行:import type { Packet } from "./Card"; const Dashboard = (props: { organization_id: string }) => { const { data } = api.example.getAllUserPackets.useQuery({ organization_id: props.organization_id, }); // 后续渲染逻辑保持不变 };
方案2:修正自定义类型的错误
如果坚持手动定义类型,需要严格对齐Prisma模型:
// Card组件中的自定义类型 export type Tag = { id: string; // 改为string,匹配Prisma的cuid类型 tagName: string; }; export type Packet = { id: string; title: string; description: string; author_id: string; deadline: Date; createdAt: Date; updatedAt: Date; is_priority_high: boolean | null; // 改为可选,匹配Prisma的Boolean? progress_indication: 'CREATED' | 'IN_PROGRESS' | 'COMPLETED'; // 替换为实际的Progress枚举值 card_author_name: string | null; // 改为可选,匹配Prisma的String? organization_id: string; is_org_admin: boolean | null; // 改为可选,匹配Prisma的Boolean? tags: Tag[]; };
注意:需要根据Prisma中定义的Progress枚举实际值,调整progress_indication的字符串字面量类型。
内容的提问来源于stack exchange,提问作者Zacharyad
相关产品推荐
相关产品推荐

