看起来这是不允许的。 requireJS在以下内容上抛出错误(this post与内部模块解决不同):
element.ts:
import runProperties = require('./run-properties');
export class Element {
public static factory (element : IElement) : Element {
switch (element.type) {
case TYPE.RUN_PROPERTIES :
return new runProperties.RunProperties().deserialize(<runProperties.IRunProperties>element);
}
return null;
}
}
运行properties.ts:
import element = require('./element');
export class RunProperties extends element.Element implements IRunProperties {
}
答案 0 :(得分:24)
不,模块不能具有循环依赖关系,除非它们在同一个文件中。每个文件都是按顺序,同步处理的,因此当它转到第二个文件时,完整的文件定义(包括所有导出)都没有完成,第二个文件立即尝试要求/引用第一个文件,并且等等。
通常,您可以通过将接口或基类引入公共定义文件(仅基本上是接口)并让其他文件将其用作公共接口来打破循环依赖关系。而不是直接引用类。这是许多平台中的典型模式。
答案 1 :(得分:2)
我有同样的问题,我能够通过创建工厂类来修复它,该工厂类允许注册子类并使用Generics进行实例化。
参考:https://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-generics
请参阅以下示例代码:
基类(abstract.control.ts)
export type AbstracControlOptions = {
key?:string;
}
export abstract class AbstractControl {
key:string;
constructor(options:AbstracControlOptions){
this.key = options.key;
}
}
父类(container.ts)
import { AbstractControl, AbstracControlOptions } from './abstract.control';
import { Factory } from './factory';
export { AbstracControlOptions };
export abstract class Container extends AbstractControl {
children: AbstractControl[] = [];
constructor(options: AbstracControlOptions) {
super(options);
}
addChild(options: { type: string }) {
var Control:any = Factory.ControlMap[options.type];
if (Control) {
this.children.push(Factory.create(Control, options));
}
}
}
我不再需要导入子类,因为我使用factory.ts来实例化子类。
工厂类(factory.ts)
import {AbstractControl, AbstracControlOptions} from './abstract.control';
type ControlMap<T extends AbstractControl> = {
[type:string]:T
};
export class Factory{
static ControlMap: ControlMap<any> = {};
static create<T extends AbstractControl>(c: { new ({}): T; }, options: AbstracControlOptions): T {
return new c(options);
}
}
虽然似乎在c: { new ({}): T }
调用了类构造函数,但它实际上并没有调用它。但是通过new
运算符获取对构造函数的引用。在我的情况下,构造函数的参数{}
是必需的,因为基类AbstractControl
需要它。
(1)儿童班(layout.ts)
import { Factory } from './factory';
import { Container, AbstracControlOptions } from './container';
export type LayoutlOptions = AbstracControlOptions & {
type:"layout";
}
export class Layout extends Container {
type: string = "layout";
constructor(options:LayoutlOptions) {
super(options);
}
}
Factory.ControlMap["layout"] = Layout;
(2)儿童班(repeater.ts)
import { Factory } from './factory'
import { Container, AbstracControlOptions } from './container';
export type RepeaterOptions = AbstracControlOptions & {
type: "repeater";
}
export class Repeater extends Container {
type: string = "repeater";
constructor(options:RepeaterOptions) {
super(options);
}
}
Factory.ControlMap["repeater"] = Repeater;