静态只读成员分配=> TypeError:XXX不是构造函数

时间:2018-07-13 19:44:48

标签: javascript typescript jestjs typeerror

我遇到带有静态只读成员的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)
    });
});

此错误是什么意思?

  • 打字稿版本为2.7.2
  • 笑话22.0.2
  • ts-jest 22.0.0

1 个答案:

答案 0 :(得分:1)

如果您将控制台日志添加到pointutil.ts,则错误更容易理解:

import {Point} from "./point";

console.log('Point:', Point);

export class PointUtil {
    public static readonly origin: Point = new Point(12, 2);
}

这表明Pointundefined(不是构造函数:-)发生这种情况的原因是point.tspointUtil.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.tspoint.ts的求值顺序相反,并且错误将消失,因为pointUtil.ts在最初未定义的point.ts上不会失败。

PointUtil

尽管这是一个骇人听闻的解决方案,所以最好避免循环,并将立即需要import './pointUtil' import {Point} from './point' describe("REPL test", () => { .. }); 的定义放在Point模块本身中。实际上,无论如何,point.ts更适合作为origin上的静态属性。