如果扩展了目标类,则TypeScript合并的声明组成将不起作用

问题描述

我需要使用已扩展的TypeScript class,并与其他一些脚本一起编写。我发现这篇文章(和其他一些喜欢的文章显示了一种我认为可以使用的模式:

https://www.typescriptlang.org/docs/handbook/mixins.html

在此使用上一篇文章中的示例代码作为最小重复说明了我的困境。

working.test.ts (原始)

// Each mixin is a Traditional ES class
class Jumpable {
  jump() {}
}

class Duckable {
  duck() {}
}

// Including the base
class Sprite {
  x = 0;
  y = 0;
}

// Then you create an interface which merges
// the expected mixins with the same name as your base
interface Sprite extends Jumpable,Duckable {}
// Apply the mixins into the base class via
// the JS at runtime
applyMixins(Sprite,[Jumpable,Duckable]);

let player = new Sprite();
player.jump();
console.log(player.x,player.y);

// This can live anywhere in your codebase:
function applyMixins(derivedCtor: any,constructors: any[]) {
  constructors.forEach((baseCtor) => {
    Object.getownPropertyNames(baseCtor.prototype).forEach((name) => {
      Object.defineProperty(
        derivedCtor.prototype,name,Object.getownPropertyDescriptor(baseCtor.prototype,name)
      );
    });
  });
}

上面的代码运行良好,但是,如果我们添加一个中间类,说Fairy,然后再Sprite进行扩展,则会遇到错误

broken.test.ts

// Each mixin is a Traditional ES class
class Jumpable {
  jump() {}
}

class Duckable {
  duck() {}
}

class Fairy {
  z = "z"
}

// Including the base
class Sprite extends Fairy {
  x = 0;
  y = 0;
}

// Then you create an interface which merges
// the expected mixins with the same name as your base
interface Sprite extends Jumpable,name)
      );
    });
  });
}

这将引发以下错误

TypeError: Cannot call a class as a function

引发错误的特定行是Sprite类的实例化:

let player = new Sprite();

根据我所见过的有关该错误的其他每篇文章解决方案是使用new关键字来调用该类……但这已经在发生了……

对于发生这种情况的原因我感到非常迷惑,感觉就像是TypeScript内部隐藏的某些东西正在崩溃...

编辑 事实证明,只有当我使用Jest运行它们,使用ts-node或在TypeScript游乐场工作时,这些文件才会引发错误

解决方法

问题出在Jest,而在我的仓库中为此配置。我正在将JS存储库转换为TypeScript的过程中,因此,尚未为TypeScript正确设置Jest。

这是我的固定方法:

  1. 删除旧的jest.config.jsbabel.config.js,并从依赖项中删除(现在)不必要的babelbabel-jest和其他babel插件。
  2. ts-jest@types/jest添加到devDependencies
  3. 使用ts-jest通过yarn ts-jest config:init创建一个新的jest配置
  4. 利润!

我困惑的主要根源实际上是错误消息导致我在jest GH回购上遇到了一个问题,其中(几乎)所有解决方案实际上都是针对纯JS的,而我试图将它们应用于TS。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...