如何在Typescript中表示Abstract类的任何子类的类型?

问题描述 投票:0回答:2

假设

abstract class A {};
class B extends A {};
class C extends A {};

我想接受A的任何子类作为参数。

function foo(Subclass: A){
   const obj = new Subclass();
}

这不会起作用。我收到错误

此表达式不可构造。类型“ BaseController”没有构造签名。

然后我尝试了

function foo(Subclass: typeof A){   
   const obj = new Subclass();
}

现在我得到了错误

无法创建抽象类的实例。ts(2511)

因为假设我传递的是A,而不是A的子类。

可以实现吗?我如何使它工作?

node.js typescript oop inheritance abstract-class
2个回答
0
投票

为此,您需要通过其构造函数引用来引用该类。

abstract class A {};
class B extends A {};
class C extends A {};

function foo(Subclass: new () => A) {   
   const obj = new Subclass();
}

在这种情况下,您可以将BC都传递给foo,因为它们具有构造函数。 A将不会被接受,因为抽象类上没有构造函数。


0
投票

我认为您应该将注释更改为以下内容:

function foo(subclass: new () => A) {
  const obj = new subclass();
}

[这里,我们说subclassnewable(即,这是您使用new运算符调用的构造函数),不带任何参数,并构造一个可分配给new的值。只要它具有无参数构造函数,它就应该接受A的任何具体子类:

A

它不接受foo(B); // okay foo(C); // okay 本身,因为抽象类构造函数不认为A可行:

new

哦,作为为编写有关堆栈溢出问题的示例TypeScript代码的人们的注释:请注意,TypeScript的类型系统为foo(A); // error, A is abstract 。通过给出的示例定义,可以将structuralAB的实例视为相同的C类型。还有empty,所以它也可以工作:

all objects are assignable to the empty type

为了防止这种情况,您应该在foo(Date); // okay also A和/或B中添加属性以在结构上区分它们,例如:

C

这将导致更多预期的行为:

abstract class A {
  a = "A"
};
class B extends A {
  b = "B"
};
class C extends A {
  c = "C"
};

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

foo(B); // okay foo(C); // okay foo(A); // error, A is abstract foo(Date); // error, 'a' is missing

© www.soinside.com 2019 - 2024. All rights reserved.