Typescript 将无法评估包含未解析类型参数的条件类型。你可以通过重载来解决这个问题:
class A {
private name!: string
constructor() {}
}
class B {
private age!: number
constructor() {}
}
const map = { A, B }
function create2<T extends keyof typeof map>(name: T, ...params: ConstructorParameters<typeof map[T]>): InstanceType<typeof map[T]>
function create2(name: keyof typeof map, ...params: ConstructorParameters<typeof map[keyof typeof map]>): InstanceType<typeof map[keyof typeof map]> {
return new map[name](...params);
}
I added InstanceType
关于返回类型。typeof map[keyof typeof map]
将成为联盟typeof A | typeof B
(即任一类)。由于我们返回一个实例,因此我们需要使用InstanceType
得到那个。
如果构造函数有参数,上面的版本实际上将不起作用。这是因为 Typescript 无法遵循这一点params
and map[name]
以任何方式相关。所以TS看到new (A | B)(...(parmsForA | paramsForB)
这只是有时安全(如果A
与paramsForB
这将是一个错误)
现在,既然我们知道两者实际上是相关的,那么这是类型断言的一个很好的用途:
class A {
constructor(public name: string) {}
}
class B {
constructor(public age: number, public address: string) {}
}
const map = { A, B }
function create2<T extends keyof typeof map>(name: T, ...params: ConstructorParameters<typeof map[T]>): InstanceType<typeof map[T]>
function create2(name: keyof typeof map, ...params: any[]): InstanceType<typeof map[keyof typeof map]> {
return new (map[name] as any)(...params)
}