我有一个抽象类Base
,它接受要在类中使用的类型变量<T>
。然后我有许多显式定义类型的派生类,例如class Derived extends Base<string> {...}
我想有一个变量(或变量数组(,其类型可以是这些派生类中的任何一个,无论<T>
是什么。然后,我希望能够使用该变量来创建这些派生类的新实例。
这是我尝试过的一些代码。从那里,我迷路了。
打字脚本游乐场链接
abstract class Base<T> {
abstract value: T;
}
class Derived extends Base<string> {
value = 'Hello world!';
}
class SecondDerived extends Base<number> {
value = 1234;
}
// This has type (typeof Derived | typeof SecondDerived)
let classes_A = [Derived, SecondDerived];
// This obviously works too, but with many derived classes can get long and tedious
let classes_B: (typeof Derived | typeof SecondDerived)[] = [];
classes_B.push(Derived);
classes_B.push(SecondDerived);
// This does NOT work
let classes_C: Base<any>[] = [];
classes_C.push(Derived); // "typeof Derived is not assignable to type Base<any>"
// This does NOT work
let classes_D: Base<unknown>[] = [];
classes_D.push(Derived); // "typeof Derived is not assignable to type Base<unknown>"
// This does NOT work
let classes_E: Base<string>[] = [];
classes_E.push(Derived); // "typeof Derived is not assignable to type Base<string>"
// This does NOT work
let classes_F: (typeof Base)[] = [];
classes_F.push(Derived); // "typeof Derived is not assignable to typeof Base"
我的建议是这样的:
let classes: Array<new (...args: any) => Base<any>> = [];
classes.push(Derived); // okay
classes.push(SecondDerived); // okay
数组的元素类型应该是"任何T
的任何子类型的Base<T>
的构造函数"。 要说"X
的构造函数"作为类型,请使用new
签名,例如new () => X
。 请注意,签名指定构造函数所需的类型和数量参数;如果你不在乎,那么你可以使用any
或any[]
类型的 REST 参数,例如new (...args: any) => X
。
由于您正在构建的类型是任何T
的任何子类型的Base<T>
,并且您可能不需要跟踪哪个子类型,因此Base<any>
可能已经足够好了。(如果没有,那么请详细说明一个不起作用的用例(。
好的,希望有帮助;祝你好运!
操场链接到代码
您需要为构造函数定义类型:
type CtorBase = new () => Base<any>;
现在你可以使用它来保存 Base 的构造函数列表:
let classes_C: CtorBase [] = [];
classes_C.push(Derived);