javascript - 静态只读成员分配 => TypeError : XXX is not a constructor

标签 javascript typescript jestjs typeerror

我在使用静态只读成员时遇到了 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)

这个错误是什么意思?

  • Typescript 版本为 2.7.2
  • 开 Jest 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);
}

这表明 Pointundefined (这不是构造函数 :-) 发生这种情况的原因是 point.tspointUtil.ts相互导入并创建循环模块依赖关系。它与测试无关,因为错误会被任何导入 point.ts 的模块触发。 .

当模块 point.ts被评估,它触发了 pointUtil.ts 的评估,进口的值(value)PointpointUtil.ts在评估 point.ts 之前将是未定义的模块已经完成。但是,由于定义了静态origin属性(property)等于做

PointUtil.origin = new Point(12, 2);

意思是PointpointUtil.ts 之前使用(因此 point.ts )已被评估,导致错误。

模块 point.ts还使用了来自 pointUtil.ts 的导入, 但这是在 dummyCalc 里面方法,因此在初始模块评估期间不会对其进行评估。这意味着如果您导入 pointUtil.ts之前point.tsrepl.test.tspoint.ts的评价顺序和 pointUtil.ts被逆转,错误就会消失,因为point.ts不会在最初未定义的 PointUtil 上失败.

import './pointUtil'
import {Point} from './point'

describe("REPL test", () => {
  ..
});

虽然这是一个 hacky 解决方案,因此最好避免循环并放置立即需要 Point 的定义。在point.ts模块本身。事实上,origin更适合作为 Point 上的静态属性无论如何。

关于javascript - 静态只读成员分配 => TypeError : XXX is not a constructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51331912/

相关文章:

javascript - 按键值对 Javascript 中的对象数组进行排序

javascript - Twig 模板无法识别 Javascript

javascript - 每秒更新 Javascript 中的文本框值

javascript - 如何检索 mat-checkbox 值

typescript - 在 TypeScript 中输入类

javascript - 使用 MobX 存储循环引用进行设置测试

javascript - 从 computeDigest(algorithm, value) byte[] 取回字符串表示

json - 在配置文件 tsconfig.json 中找不到输入

javascript - 如何使用 Jest/Enzyme 测试去抖功能?

reactjs - 如何使用 Jest 测试测试窗口对象