javascript - 静态只读成员赋值 => TypeError: XXX is not a constructor
问题描述
我遇到了带有静态只读成员的 Typescript/Jest 的问题。这里是一个基本的例子。
项目结构基于此启动项目:https ://github.com/alexjoverm/typescript-library-starter ,如果它可以帮助重现问题。
点.ts
import {PointUtil} from "./pointUtil";
export class Point
{
public x: number;
public y: number;
public constructor(x: number, y: number)
{
this.x = x;
this.y = y;
}
public dummyCalc() : number
{
return this.x + this.y + PointUtil.origin.x + PointUtil.origin.y;
}
}
pointutil.ts
import {Point} from "./point";
export class PointUtil {
public static readonly origin: Point = new Point(12, 2);
}
repl.test.ts
import {Point} from "../src/point";
describe("REPL test", () => {
it("dummy test", () => {
expect(new Point(1, 1).dummyCalc()).toEqual(16)
});
});
错误
运行测试套件时,我得到
● Test suite failed to run
TypeError: _point.Point is not a constructor
3 | export class PointUtil {
4 | public static readonly origin: Point = new Point(12, 2);
> 5 | }
6 |
at src/pointUtil.ts:5:24
at Object.<anonymous> (src/pointUtil.ts:7:2)
at Object.<anonymous> (src/point.ts:1:4237)
at Object.<anonymous> (test/repl.test.ts:1:1181)
这个错误是什么意思?
- 打字稿版本是 2.7.2
- 开玩笑 22.0.2
- ts-jest 22.0.0
解决方案
如果您将控制台日志添加到以下位置,则该错误更容易理解pointutil.ts
:
import {Point} from "./point";
console.log('Point:', Point);
export class PointUtil {
public static readonly origin: Point = new Point(12, 2);
}
这表明Point
is undefined
(它不是构造函数:-) 发生这种情况的原因是相互导入point.ts
并pointUtil.ts
创建循环模块依赖项。它与测试无关,因为任何导入的模块都会触发错误point.ts
。
当模块point.ts
被评估并触发 的评估时pointUtil.ts
,导入的值Point
将pointUtil.ts
是不确定的,直到point.ts
模块的评估完成。但是,由于静态origin
属性的定义相当于做
PointUtil.origin = new Point(12, 2);
这意味着Point
get 之前pointUtil.ts
(因此point.ts
)已被评估,导致错误。
Modulepoint.ts
也使用 import from pointUtil.ts
,但这是在dummyCalc
方法内部,因此在初始模块评估期间不会对其进行评估。这意味着如果您在inpointUtil.ts
之前导入,则and的评估顺序会颠倒过来,并且错误将消失,因为在最初的 undefined 上不会失败。point.ts
repl.test.ts
point.ts
pointUtil.ts
point.ts
PointUtil
import './pointUtil'
import {Point} from './point'
describe("REPL test", () => {
..
});
虽然这是一个 hacky 解决方案,所以最好避免循环并将立即需要的定义放在Point
模块point.ts
本身中。事实上,无论如何origin
更适合作为静态属性。Point
推荐阅读
- reactjs - 反应光滑的意外令牌
- reactjs - Typescript 通用函数,它根据其他变量提供组件属性
- c# - EF不会从多对多关系加载数据
- firebase - 将应用统计数据保存在 Firestore 中并导出到 Bigquery 或直接保存 Bigquery?
- python - 通过 CNN 检测直线的旋转角度
- maps - 如何为 HERE SDK for android(导航版)创建凭据并下载 HERE SDK
- c# - 在列表框(WPF)中选中绑定复选框
- laravel - 如何在使用 CKEditor 的编辑表单中呈现文本
- github - GitHub 操作中的 CMake 问题
- c++ - 如何对按第二种类型(int)排序的二维数组对进行排序?