我在修复 Typescript 错误时遇到了麻烦。这是代码:
import { PrismaClient, dog, cat, bird } from '@prisma/client'
export type AnyPrismaClientType = PrismaClient["dog"] | PrismaClient["cat"] | PrismaClient["bird"]
export function makePrismaFromName(name: string): AnyPrismaClientType {
const prismaClient = new PrismaClient()
var client;
switch (name) {
case "dog": {
client = prismaClient.dog;
break;
}
case "cat": {
client = prismaClient.cat;
break;
}
case "bird": {
client = prismaClient.bird;
break;
}
default: {
const msg = `unrecognized animal type ${String(name)}`;
throw (msg);
}
}
return client;
}
const myClient = makePrismaFromName('dog');
const inactiveAccountCount = await prismaClient.count( // --> This is the line giving me the type error.
{
where: {
stray: false,
clean: true,
}
}
);
这是错误:
This expression is not callable.
Each member of the union type '(<T extends dogCountArgs>(args?: Subset<T, DogCountArgs<DefaultArgs>> | undefined) =>
PrismaPromise<T extends Record_2<"select", any> ? T["select"] extends true ? number : { [P in keyof T["select"]]: P extends
keyof DogCountAggregateOutputType ? DogCountAggregateOutputType[P] : never; } : number>) | (<T ...' has signatures, but none
of those signatures are compatible with each other.
您在这里面临的问题是,所有这些返回类型 (
dog, cat, or bird
) 都会给 TS 带来混乱,它无法确定使用哪种类型来运行 count 方法。
您正在寻找的解决方案是使用泛型,您的
makePrismaFromName
函数会将这个泛型定义为某种类型的扩展,为了简洁起见,这里称为 Animal ,并且返回类型与提供的泛型匹配。这可以这样实现:
import { PrismaClient } from '@prisma/client'
type Animal = 'dog' | 'cat' | 'bird';
export function makePrismaFromName<T extends Animal>(name: T): PrismaClient[T] {
const prismaClient = new PrismaClient();
switch (name) {
case "dog":
return prismaClient.dog as PrismaClient[T];
case "cat":
return prismaClient.cat as PrismaClient[T];
case "bird":
return prismaClient.bird as PrismaClient[T];
default:
throw new Error(`Unrecognized animal type: ${name}`);
}
}
请注意,此处的类型断言是为了帮助 TS 根据给定的泛型找出类型。
您的调用函数和其他部分将保持不变。