在 TypeScript 中为具有类型变量的抽象类中的派生类分配泛型类型
Posted
技术标签:
【中文标题】在 TypeScript 中为具有类型变量的抽象类中的派生类分配泛型类型【英文标题】:Assigning a generic type for derived classes from an abstract class with type variables in TypeScript 【发布时间】:2020-05-22 23:02:35 【问题描述】:我有一个抽象类Base
,它接受一个类型变量<T>
在类中使用。然后我有很多明确定义类型的派生类,比如class Derived extends Base<string> ...
我想要一个变量(或变量数组),其类型可以是任何派生类,无论<T>
是什么。然后我希望能够使用该变量来创建这些派生类的新实例。
这是我尝试过的一些代码。从那里,我迷路了。
TypeScript Playground link
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"
【问题讨论】:
【参考方案1】:你需要为构造函数定义类型:
type CtorBase = new () => Base<any>;
现在您可以使用它来保存 Base 的构造函数列表:
let classes_C: CtorBase [] = [];
classes_C.push(Derived);
【讨论】:
大概是classes_X
持有constructors而不是instances,对吧?
感谢您的回复,但不幸的是它并没有解决这个问题。我实际上确实想将类类型放在这些数组中,而不是类的实例中。所以我确实打算做classes_C.push(Derived)
@jcalz 是的,我想持有构造函数,而不是类的实例
好的,更改了我的编辑。第一次没听懂,抱歉:)
这也解决了。我也喜欢这样,因为我可以根据所需的参数定义多种类型,然后使用所有这些。谢谢!【参考方案2】:
我的建议是这样的:
let classes: Array<new (...args: any) => Base<any>> = [];
classes.push(Derived); // okay
classes.push(SecondDerived); // okay
数组的元素类型应该是“任何Base<T>
的任何T
子类型的构造函数”。要说“X
的构造函数”作为类型,您可以使用new
able signature,如new () => X
。请注意,签名指定构造函数期望的类型和数量参数;如果你不关心,那么你可以使用any
或any[]
类型的rest argument,比如new (...args: any) => X
。
由于您正在构建的类型是任何T
的Base<T>
的任何子类型,并且您可能不需要跟踪哪个,那么Base<any>
可能就足够了。 (如果不是,请详细说明这不起作用的用例)。
好的,希望对您有所帮助;祝你好运!
Playground link to code
【讨论】:
这解决了!我也有需要强制执行的参数,但它们对于每个派生类都是相同的,所以这是完美的。谢谢!以上是关于在 TypeScript 中为具有类型变量的抽象类中的派生类分配泛型类型的主要内容,如果未能解决你的问题,请参考以下文章