在 TypeScript 中使用类型变量为抽象类的派生类分配泛型类型



我有一个抽象类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。 请注意,签名指定构造函数所需的类型和数量参数;如果你不在乎,那么你可以使用anyany[]类型的 REST 参数,例如new (...args: any) => X

由于您正在构建的类型是任何T的任何子类型的Base<T>,并且您可能不需要跟踪哪个子类型,因此Base<any>可能已经足够好了。(如果没有,那么请详细说明一个不起作用的用例(。

好的,希望有帮助;祝你好运!

操场链接到代码

您需要为构造函数定义类型:

type CtorBase = new () => Base<any>;

现在你可以使用它来保存 Base 的构造函数列表:

let classes_C: CtorBase [] = [];
classes_C.push(Derived);

最新更新