【问题标题】:How to represent the Type of any Subclass of an Abstract class in Typescript?如何在 Typescript 中表示抽象类的任何子类的类型?
【发布时间】:2020-05-23 03:29:45
【问题描述】:

假设

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 的子类。

它可以实现吗?我如何让它发挥作用?

【问题讨论】:

  • 您在寻找this吗?我不确定您为什么在示例代码中写new A(),因为A 始终是抽象构造函数,而不是您传入的任何内容。也许您的意思是new Subclass()
  • 我的错。是new Subclass()
  • 如果您将一个已知的类传递给foo,您是否有理由不只构建该类?
  • @jcalz 成功了。
  • @Leon 未知。在我的具体情况下,它可以是任何Controller。 A 是BaseController

标签: node.js typescript oop inheritance abstract-class


【解决方案1】:

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

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

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

foo(B); // okay
foo(C); // okay

它本身不会接受A,因为抽象类构造函数不被认为是newable:

foo(A); // error, A is abstract

哦,作为针对 Stack Overflow 问题制作示例 TypeScript 代码的人的说明:请注意,TypeScript 的类型系统是 structural。根据您给出的示例定义,ABC 的实例被认为是相同的 empty 类型。还有all objects are assignable to the empty type,所以这也有效:

foo(Date); // okay also

为防止这种情况,您应该向AB 和/或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

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

Playground link to code

【讨论】:

    【解决方案2】:

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

    abstract class A {};
    class B extends A {};
    class C extends A {};
    
    function foo(Subclass: new () => A) {   
       const obj = new Subclass();
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多