Prisma函数传入可选自定义select参数时如何保留返回值强类型?
解决方案
核心思路是使用TypeScript函数重载,为不同入参场景单独定义返回类型,搭配Prisma内置的GetPayload工具类型实现强类型推导:
// 无参数调用重载:返回默认选择字段的类型 function listAllTypes(): Promise<{ name: string; description: string }[]>; // 传入自定义select重载:返回对应字段的推导类型 function listAllTypes<T extends Prisma.UserTypeSelect>(select: T): Promise<Prisma.UserTypeGetPayload<{ select: T }>[]>; // 函数实现逻辑和原有逻辑一致 function listAllTypes<T extends Prisma.UserTypeSelect>(select?: T) { return select === undefined ? prisma.userType.findMany({ select: { name: true, description: true } }) : prisma.userType.findMany({ select }); }
效果验证
const test = async () => { // x类型自动推导为 { name: string; description: string; }[] const x = await listAllTypes(); // y类型自动推导为 { name: string; }[] const y = await listAllTypes({ name: true }); };
原理解释
原有写法的问题在于TypeScript无法将运行时的条件分支判断和泛型返回类型做绑定,因此会把两个分支的返回类型合并为联合类型。使用函数重载后,TypeScript会在调用阶段直接根据入参匹配对应的重载签名,直接得到对应场景的返回类型,不需要依赖运行时分支的类型收窄。
Prisma内置的*GetPayload工具类型可以自动根据传入的查询配置(select/include等)生成对应的返回值类型,无需手动编写类型定义。
内容的提问来源于stack exchange,提问作者David Horstman
相关产品推荐
相关产品推荐

