【问题标题】:Typescript - returning the constructor of a child class from an abstract methodTypescript - 从抽象方法返回子类的构造函数
【发布时间】:2019-12-12 00:15:07
【问题描述】:

我有抽象类 Child 和抽象类 Parent 如下:

abstract class Child {

}

abstract class Parent {
  abstract getChild(): typeof Child; // <-- want a class that extends Child
}

这个想法是 Parent 和 Child 都由实际的实现类扩展,其中每个实现 Parent 都知道它的 Child 类是什么:

class ActualChild extends Child {

}

class ActualParent extends Parent {
  getChild() {
    return ActualChild;
  }
}

就TS而言,返回的对象是Child类型,因此无法实例化。

我尝试了许多不同的方法来解释该函数仅返回一个扩展 Child 的类而没有成功。

有什么办法可以输入吗?

【问题讨论】:

  • getChild(): typeof ActualChild { return ActualChild; } ?
  • 而这些Child 的具体子类...它们都是零参数构造函数还是需要某种构造函数参数?

标签: typescript abstract-class


【解决方案1】:

我认为您正在寻找 genericsnew constaint

abstract class Child {

}

abstract class Parent<TChild extends Child> {
  abstract getChild(): { new(): TChild}; 
}

然后

class ActualChild extends Child {

}

class ActualParent extends Parent<ActualChild> {
  getChild() {
    return ActualChild;
  }
}

Typescript Playground Approves

就TS而言,返回的对象是Child类型,因此无法实例化。

这在技术上是不正确的。返回的对象是类类型(子类)。您的措辞 object is of type Child 通常表示 Child 类型的实例化对象,这是不正确的。

【讨论】:

  • 请注意,仅当需要保留 ActualChild 的特化时才需要泛型,否则 abstract class Parent { abstract getChild(): { new(): Child }; } 工作正常。这与我的答案之间的唯一区别是一个为new 约束提供规范名称的接口。
  • 是的,我假设他的评论每个实现 Parent 都知道它的 Child 类是什么提出了这个要求。
  • 我只是认为getChild()Parent 的每个实现中的返回值将与Child 的实现紧密耦合。不过,我认为将专业化作为泛型提供并没有什么坏处。
【解决方案2】:

声明一个interface 来描述abstract class Child 本身,并将getChild() 的返回类型更改为该接口。

interface ChildConstructor {
  new(): Child;
}


abstract class Parent {
  abstract getChild(): ChildConstructor;
}

那么这将在没有 TypeScript 错误的情况下编译:

const parentInstance: Parent = new ActualParent();
const ChildClass = parentInstance.getChild();
const childInstance = new ChildClass();

【讨论】:

  • 泛型不是我想要的,因为在使用此代码的级别上,我没有任何可以参考的具体实现类。如果出于我不理解的原因,此解决方案有效(这与 TS 与实例化 Child 有何不同?)。感谢您的回答,并感谢其他所有人的努力:)
  • 我不得不抱怨它很丑,但我原以为会有一些简单的内置语法
猜你喜欢
  • 1970-01-01
  • 2016-08-21
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 2021-11-24
相关资源
最近更新 更多