问题描述
我需要使用已扩展的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。
这是我的固定方法:
- 删除旧的
jest.config.js
和babel.config.js
,并从依赖项中删除(现在)不必要的babel
,babel-jest
和其他babel插件。 - 将
ts-jest
和@types/jest
添加到devDependencies
。 - 使用ts-jest通过
yarn ts-jest config:init
创建一个新的jest配置 - 利润!
我困惑的主要根源实际上是错误消息导致我在jest
GH回购上遇到了一个问题,其中(几乎)所有解决方案实际上都是针对纯JS的,而我试图将它们应用于TS。