在TypeScript中使用Prisma Client引用子模型的类型问题
Prisma 查询关联数据后的类型正确处理方式
你遇到的问题是因为@prisma/client导出的Services是模型的基础类型,只包含模型本身定义的字段,不会自动包含关联的sub_services——只有当你在查询时显式用include或select指定关联字段后,返回的数据才会包含这些字段,但默认类型没同步更新。
推荐使用 Prisma 自带的类型推导方案
Prisma 生成的客户端提供了专门的类型工具来获取查询后的返回类型,完全不需要手动写自定义类型,具体有两种方式:
方式1:直接通过typeof推导查询结果类型
这种方式最简单,直接从查询结果的类型中提取:
const services = await prisma.services.findMany({ where: { deleted: false }, include: { sub_services: true } }); // 从查询结果数组中提取单个元素的类型 type ServiceWithSubServices = typeof services[0];
方式2:用Prisma.ServicesGetPayload精准指定查询选项
如果需要提前定义类型(比如在组件文件中单独引用),可以用 Prisma 提供的GetPayload类型,结合查询选项来生成:
import { Prisma } from '@prisma/client'; // 定义查询的关联包含规则,用`as const`让 TS 保留字面量类型 const includeSubServices = { include: { sub_services: true } } as const; // 生成包含 sub_services 的完整类型 type ServiceWithSubServices = Prisma.ServicesGetPayload<typeof includeSubServices>;
在 React 组件中使用正确的类型
把上面生成的ServiceWithSubServices用到组件的 props 类型中即可:
import { ServiceWithSubServices } from './path-to-your-types'; const MyComponent: React.FC<{ service: ServiceWithSubServices }> = ({ service }) => { return ( <> {service.sub_services.map(subService => ( <div key={subService.id}>{subService.name}</div> ))} </> ); };
关于你之前的自定义类型
你之前写的自定义类型有两个问题:
- 泛型写法错误(
<Services>是无效的泛型定义) - 使用
Partial<Services>会把原模型的所有字段变成可选,完全没必要——查询返回的原字段都是存在的,只是多了sub_services
如果一定要手动写,正确的写法应该是:
import { Services, SubServices } from '@prisma/client'; type ServiceWithSubServices = Services & { sub_services: SubServices[]; };
但还是推荐用 Prisma 自带的类型推导,因为如果后续修改查询的include/select规则,自带类型会自动同步更新,不需要手动维护。
内容的提问来源于stack exchange,提问作者Boardy
相关产品推荐
相关产品推荐

