如何在Prisma中实现动态类型?解决findUnique调用类型错误
解决Prisma动态调用findUnique的「this expression is not callable」类型错误
原代码的问题在于:prisma[model]的类型是宽泛的Prisma.Model,TypeScript无法确定具体模型的findUnique方法签名;同时idName是任意字符串,无法和对应模型的主键/唯一字段关联,导致类型不兼容,触发调用错误。
下面是无需使用any的类型安全解决方案,通过Prisma内置类型和泛型约束实现类型关联:
import { Prisma, PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); export const isFound = async < ModelName extends Prisma.ModelName, IdField extends keyof Prisma.GetFindUniqueArgs<ModelName>['where'] >( model: ModelName, id: Prisma.GetFindUniqueArgs<ModelName>['where'][IdField], idName: IdField ): Promise<boolean> => { // 仅当目标字段是数字类型时,才转换id的类型(根据你的业务需求调整) const parsedId = typeof id === 'string' && typeof (Prisma.GetFindUniqueArgs<ModelName>['where'][IdField]) === 'number' ? Number(id) : id; // 类型断言让TypeScript识别具体模型的findUnique方法 const modelInstance = prisma[model] as { findUnique: (args: Prisma.GetFindUniqueArgs<ModelName>) => Promise<unknown>; }; const result = await modelInstance.findUnique({ where: { [idName]: parsedId } as Prisma.GetFindUniqueArgs<ModelName>['where'], }); return !!result; };
关键说明:
- 泛型
ModelName约束为合法的Prisma模型名,确保传入的模型存在 IdField约束为对应模型findUnique查询支持的字段名,避免传入非法字段id的类型绑定到IdField对应的字段类型,确保参数类型匹配- 通过类型断言明确
prisma[model]的findUnique方法签名,消除调用错误
这样实现后,调用函数时如果传入错误的模型名、字段名或不匹配的id类型,TypeScript会直接抛出编译错误,完全保留类型安全性。
内容的提问来源于stack exchange,提问作者Abid
相关产品推荐
相关产品推荐

