如何让Prisma Client Extension自动关联user并保证类型安全?
解决Prisma Client Extension自动关联查询的类型推导问题
你的问题核心是Prisma Client Extension默认不会自动推导修改include参数后的返回类型,必须显式扩展模型的返回类型定义,才能让TypeScript识别自动添加的关联字段。
修改后的扩展代码
import { Prisma } from '@prisma/client' // 预定义包含user关联的Post类型 type PostWithUser = Prisma.PostGetPayload<{ include: { user: true } }> const postExtension = Prisma.defineExtension((prisma) => prisma.$extends({ name: 'postExtension', query: { post: { $allOperations({ operation, args, query }) { // 跳过不需要自动关联的批量操作 const skipOperations = [ 'createMany', 'updateMany', 'deleteMany', 'aggregate', 'count', 'groupBy' ] if (skipOperations.includes(operation)) { return query(args) } // 强制合并user关联到include参数 return query({ ...args, include: { ...(args.include || {}), user: true } }) } } }, // 显式声明Post模型读取操作的返回类型 result: { post: { findUnique: { type: PostWithUser }, findFirst: { type: PostWithUser }, findMany: { type: PostWithUser[] }, findUniqueOrThrow: { type: PostWithUser }, findFirstOrThrow: { type: PostWithUser } } } }) ) // 创建扩展后的Prisma客户端并绑定类型 type ExtendedPrisma = ReturnType<typeof postExtension> const extendedPrisma = prisma.$extends(postExtension) as ExtendedPrisma // 使用示例 async function getPost(id: string) { return extendedPrisma.post.findUnique({ where: { id } }) } // 现在PostOutput会自动包含user字段 type PostOutput = Awaited<ReturnType<typeof getPost>>
关键说明
- 显式类型声明:通过扩展的
result字段,为Post模型的每个读取操作指定返回类型为PostWithUser,让TypeScript自动识别关联字段。 - 批量操作过滤:跳过不需要添加关联的批量操作(如
createMany、count等),避免无效修改。 - 类型复用:提前定义
PostWithUser类型,统一复用所有读取操作的返回类型声明,减少重复代码。
这样修改后,调用findUnique等读取操作时,返回类型会自动包含user字段,无需手动指定泛型参数。
内容的提问来源于stack exchange,提问作者smsh
相关产品推荐
相关产品推荐

