Javascript 静态只读成员分配=>;类型错误:XXX不是构造函数

Javascript 静态只读成员分配=>;类型错误:XXX不是构造函数,javascript,typescript,jestjs,typeerror,Javascript,Typescript,Jestjs,Typeerror,我在使用静态只读成员的Typescript/Jest时遇到了一个问题。这里有一个基本的例子 该项目的结构是基于这个启动项目:如果它可以帮助复制问题 point.ts import {PointUtil} from "./pointUtil"; export class Point { public x: number; public y: number; public constructor(x: number, y: number) { th

我在使用静态只读成员的Typescript/Jest时遇到了一个问题。这里有一个基本的例子

该项目的结构是基于这个启动项目:如果它可以帮助复制问题

point.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;
    }
}
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)
    });
});
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;
    }
}
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)
    });
});
repl.test.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;
    }
}
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)
    });
});
错误

当运行我得到的测试套件时

● 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)
● 测试套件无法运行
TypeError:_point.point不是构造函数
3 |导出类PointUtil{
4 |公共静态只读原点:点=新点(12,2);
> 5 | }
6 | 
在src/pointUtil.ts:5:24
反对。(src/pointUtil.ts:7:2)
反对。(src/point.ts:1:4237)
反对。(试验/补充试验ts:1:1181)
这个错误意味着什么

  • Typescript版本是2.7.2
  • 笑话22.0.2
  • ts笑话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);
}
这表明
未定义的
(它不是构造函数:-)发生这种情况的原因是
点.ts
点util.ts
相互导入并创建循环模块依赖关系。它与测试无关,因为任何导入
point.ts
的模块都会触发错误

当对模块
point.ts
求值时,它会触发对
pointUtil.ts
的求值,在
pointUtil.ts
模块求值完成之前,导入的
point
中的
值将不被定义。但是,由于static
origin
属性的定义相当于

PointUtil.origin = new Point(12, 2);
这意味着在评估
pointUtil.ts
(因此
Point.ts
)之前使用
Point
,从而导致错误

模块
point.ts
也使用从
pointUtil.ts
导入,但这在
dummyCalc
方法中,因此在初始模块求值期间不会对其求值。这意味着,如果在
repl.test.ts
中的
pointUtil.ts
之前导入
pointUtil.ts
,则
pointUtil.ts
pointUtil.ts
的求值顺序将颠倒,错误将消失,因为
point.ts
不会在最初未定义的
pointUtil
上失败

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

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

不过,这是一个很难解决的解决方案,因此最好避免这种循环,将立即需要
Point
的定义放在
Point.ts
模块本身中。事实上,
origin
更适合作为
的静态属性。

解决方案对您有效吗?