Typescript - 将类类型存储为变量,以便从中创建对象或其他等效功能

标签 typescript class abstract-class abstract factory-method

前言 - 我在 SO 上看过与这篇文章类似的帖子,但答案似乎并不适用。

我有一个具有以下方法的抽象类(简化):

playAnimation() {
    let animator =  this.createAnimator(this.animatorData)  
    await animator.animate()
}

Create animator 在该抽象类中具有以下定义:
abstract createAnimator(animatorData: Object): Animator

子类可能实现 createAnimator像这样:
createAnimator(animatorData: StandardAnimatorData) {
    return new RiverAnimator(animatorData.addMessage, animatorData.assetsDir) 
}

或像这样:
createAnimator(animatorData: StandardAnimatorData) {
    return new BridgeAnimator(animatorData.addMessage, animatorData.assetsDir) 
}

如您所见 - createAnimator 的两个子类的实现大致相同,除了 Animator 的类型被退回。

旁注 BridgeAnimatorRiverAnimator都实现了Animator接口(interface),但如果解决方案需要 Animator作为一个抽象类,我可以改变它。

有没有办法搬家createAnimator进入抽象基类?

理想情况下,抽象类应该有一个抽象变量,它是 createAnimator 的类的类型。应该返回。子类只会实现该变量。然后createAnimator将使用该变量返回正确类型的 Animator .

最佳答案

是的,你可以做这样的事情(我做了一个大的代码片段,所以我可以验证一切都可以编译):

interface Animator {
  animate(): Promise<void>;
}

class RiverAnimator implements Animator {
  async animate() { }
  constructor(addMessage: unknown, assetsDir: unknown) { }
}
class BridgeAnimator implements Animator {
  async animate() { }
  constructor(addMessage: unknown, assetsDir: unknown) { }
}

interface StandardAnimatorData {
  addMessage: unknown;
  assetsDir: unknown;
}

// Common interface for the constructor functions RiverAnimator and BridgeAnimator 
interface AnimatorConstructor {
  new(addMessage: unknown, assetsDir: unknown): Animator;
}

abstract class AbstractOuterClass {
  abstract animatorConstructor: AnimatorConstructor;
  animatorData: StandardAnimatorData;
  createAnimator(data: StandardAnimatorData) {
    return new this.animatorConstructor(data.addMessage, data.assetsDir);
  } 
  async playAnimation() {
    let animator = this.createAnimator(this.animatorData);
    await animator.animate();
  }
}

class SubOuterClass1 extends AbstractOuterClass {
  animatorConstructor = RiverAnimator;
}

class SubOuterClass2 extends AbstractOuterClass {
  animatorConstructor = BridgeAnimator;
}

但我不清楚这是否比实现 createAnimator 更好。在 SubOuterClass1SubOuterClass2 .

关于Typescript - 将类类型存储为变量,以便从中创建对象或其他等效功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51886775/

相关文章:

javascript - 是否可以从字符串模板文字中推断泛型类型

javascript - 处理后Angular 2修改 View html

TypeScript 联合类型推断失败

javascript - 更好的方法来处理 JavaScript 类中的状态变化

php - 调用 PHP 类

java - 为什么这个对象数组中的每个元素都会被最后一个对象覆盖?

python - 如何使用类范围而不是类方法范围初始化/定义子类?

c++ - 如何使用类型特征来定义部分抽象的模板基类?

javascript - Angular 服务和 HttpClient 类型不存在

.net - 抽象类和接口(interface)之间的主要区别是什么?