我得到了循环加载程序异常。这可能是由编译器选项"emitDecoratorMetadata":true
引起的。
我该如何解决?感谢您提供有用的重播!
我已经准备了一个最小项目来重现该错误。请查看我的临时git存储库:git repo for bug presentation
我使用两个库(typeorm
和json2typescript
),并且都使用装饰器。我在两个类属性的两个库中使用了多个装饰器。
复制步骤:
npm i
(npm 6.9.0)安装所有软件包。Visual Studio Code
打开根目录。bugexample/test/test.spec.ts
,进入调试视图并通过配置Mocha current file
开始调试。完成这些步骤后,您应该会看到异常输出。
/bugexample/node_modules/reflect-metadata/Reflect.js:553
var decorated = decorator(target, propertyKey, descriptor);
^
Error: Fatal error in JsonConvert. It is not allowed to explicitly pass "undefined" as second parameter in the @JsonProperty decorator.
Class property:
banana
Use "Any" to allow any type. You can import this class from "json2typescript".
属性banana
获取类型Banana
作为参数,由于未知原因,该类型为undefined
。库json2typescript
并非引起此问题的原因。
现在,我想解决这个问题。 我从两个模型类开始,然后以测试结束。
首先,请看一下bug_presentation/src/persistence/models/ape.model.ts
。
import { JsonObject, JsonProperty } from "json2typescript";
import { Column, Entity, OneToOne, PrimaryGeneratedColumn } from "typeorm";
import { Banana } from "./banana.model";
/**
* This is an entity class.
*
* @author Tim Lehmann <l_@freenet.de>
*/
@JsonObject("Ape")
@Entity()
export class Ape {
@PrimaryGeneratedColumn()
readonly id: number
@JsonProperty('0')
@Column()
readonly name: string = null
// the associated table holds the foreign keys
@JsonProperty('1', Banana)
@OneToOne(type => Banana, banana => banana.possessionOf, { cascade: true })
readonly banana = new Banana();
}
在第24行中,类型Banana
是传递的参数,但由于未知原因,它是当前测试的undefined
。
现在请看一下bug_presentation/src/persistence/models/banana.model.ts
。
import { JsonObject, JsonProperty } from "json2typescript";
import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from "typeorm";
import { Ape } from "./ape.model";
/**
* @author Tim Lehmann <l_@freenet.de>
*/
@JsonObject("Banana")
@Entity()
export class Banana {
@PrimaryGeneratedColumn()
private readonly id: number
@JsonProperty('0')
@Column()
readonly weight: string = null
@OneToOne(type => Ape, possessionOf => possessionOf.banana)
@JoinColumn({ name: "possessionOf" })
readonly possessionOf: Ape = new Ape();
}
第21和22行有问题。如果我将这些行注释掉,那么没有加载程序异常。
最后,请看看bug_presentation/test/test.spec.ts
。
import { expect } from "chai";
import { Ape } from "../src/persistence/models/ape.model";
import { Banana } from "../src/persistence/models/banana.model";
// const classApe = Ape;
const classBanana = Banana;
describe("check if class type exist", () => {
it('check class Ape is defined', () => {
// expect(classApe).exist;
})
it('check class Banana is defined', () => {
expect(classBanana).exist;
})
})
我要测试类型/类Banana
是否未定义,但是测试会更早中断,因为如果传递的属性(在这种情况下,类型为{{1 }})是json2typescript
。
奇怪的行为是,如果我将类Banana
分配给变量(在第6行删除注释),则定义了类型/类undefined
。
答案 0 :(得分:1)
我知道我对此事有些迟了,但是我遇到了类似的问题并找到了这篇文章。深入研究后,我意识到json2typescript根本不是问题,而是循环依赖问题。
我发现这篇非常有用的文章可以帮助我解决项目中的问题:https://medium.com/visual-development/how-to-fix-nasty-circular-dependency-issues-once-and-for-all-in-javascript-typescript-a04c987cf0de
本质上,问题是:
ape.model.ts
中,您要导入香蕉:import { Banana } from "./banana.model";
banana.model.ts
中导入猿:import { Ape } from "./ape.model";
这些模块是按顺序加载的,因此,当第一个模块被加载时(让其装成ape.model.ts
),它将尝试导入香蕉->香蕉将被加载,试图导入猿->猿还没有完成加载因此它返回的是undefined。
我所链接的文章提出的解决方案建议您创建一个internal.ts
文件来管理模块加载:
export * from './ape.model';
export * from './banana.model';
然后总是从内部加载,即在ape.model.ts
中加载
import { Banana } from './internal';