假设
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的子类。
可以实现吗?我如何使它工作?
为此,您需要通过其构造函数引用来引用该类。
abstract class A {};
class B extends A {};
class C extends A {};
function foo(Subclass: new () => A) {
const obj = new Subclass();
}
在这种情况下,您可以将B
和C
都传递给foo
,因为它们具有构造函数。 A
将不会被接受,因为抽象类上没有构造函数。
我认为您应该将注释更改为以下内容:
function foo(subclass: new () => A) {
const obj = new subclass();
}
[这里,我们说subclass
是new
able(即,这是您使用new
运算符调用的构造函数),不带任何参数,并构造一个可分配给new
的值。只要它具有无参数构造函数,它就应该接受A
的任何具体子类:
A
它不接受foo(B); // okay
foo(C); // okay
本身,因为抽象类构造函数不认为A
可行:
new
哦,作为为编写有关堆栈溢出问题的示例TypeScript代码的人们的注释:请注意,TypeScript的类型系统为foo(A); // error, A is abstract
。通过给出的示例定义,可以将structural,A
和B
的实例视为相同的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