我遇到带有静态只读成员的Typescript / Jest问题。这里是一个基本的例子。
项目结构基于以下初始项目:https://github.com/alexjoverm/typescript-library-starter,如果它可以帮助重现问题。
point.ts
class="row"
pointutil.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;
}
}
repl.test.ts
import {Point} from "./point";
export class PointUtil {
public static readonly origin: Point = new Point(12, 2);
}
错误
运行测试套件时,我会得到
import {Point} from "../src/point";
describe("REPL test", () => {
it("dummy test", () => {
expect(new Point(1, 1).dummyCalc()).toEqual(16)
});
});
此错误是什么意思?
答案 0 :(得分:1)
如果您将控制台日志添加到pointutil.ts
,则错误更容易理解:
import {Point} from "./point";
console.log('Point:', Point);
export class PointUtil {
public static readonly origin: Point = new Point(12, 2);
}
这表明Point
是undefined
(不是构造函数:-)发生这种情况的原因是point.ts
和pointUtil.ts
相互导入并创建了一个循环模块依赖性。它与测试无关,因为任何导入point.ts
的模块都会触发该错误。
在评估模块point.ts
并触发对pointUtil.ts
的评估时,在Point
中导入的pointUtil.ts
的值将是不确定的,直到{ {1}}模块已完成。但是,由于静态point.ts
属性的定义就等于
origin
这意味着PointUtil.origin = new Point(12, 2);
在Point
(因此pointUtil.ts
)被评估之前就被使用,从而导致错误。
模块point.ts
也使用来自point.ts
的导入,但这是在pointUtil.ts
方法内部,因此在初始模块评估期间不会对其进行评估。这意味着,如果在dummyCalc
中的pointUtil.ts
之前导入point.ts
,则repl.test.ts
和point.ts
的求值顺序相反,并且错误将消失,因为pointUtil.ts
在最初未定义的point.ts
上不会失败。
PointUtil
尽管这是一个骇人听闻的解决方案,所以最好避免循环,并将立即需要import './pointUtil'
import {Point} from './point'
describe("REPL test", () => {
..
});
的定义放在Point
模块本身中。实际上,无论如何,point.ts
更适合作为origin
上的静态属性。