Can typescript external modules have circular dependencies?

后端 未结 2 492
南旧
南旧 2020-12-09 17:20

It looks like this is not allowed. requireJS is throwing an error on the following (this post is different as it was resolved with internal modules):

element.ts:

2条回答
  •  抹茶落季
    2020-12-09 17:52

    I have same issue, I was able to fix it by creating factory class that allows registration of child classes and used Generics for instantiation.

    Reference: https://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-generics

    See sample code below:

    Base Class (abstract.control.ts)

    export type AbstracControlOptions = {
        key?:string;
    }
    export abstract class AbstractControl {
        key:string;
        constructor(options:AbstracControlOptions){
            this.key = options.key;
        }    
    }
    

    Parent Class (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));
            }
        }
    }
    

    I don't have to import the child classes any more, because I'm using factory.ts to instantiate the child classes.

    Factory Class(factory.ts)

    import {AbstractControl, AbstracControlOptions} from './abstract.control';
    
    type ControlMap = {
        [type:string]:T
    };
    
    export class Factory{
        static ControlMap: ControlMap = {};
        static create(c: { new ({}): T; }, options: AbstracControlOptions): T {
            return new c(options);
        } 
    }
    

    Although class constructor seems to be called at c: { new ({}): T } but it does not actually calls it. But gets the reference to the constructor via new operator. The parameter {} to the constructor in my case is required because the base class AbstractControl requires it.

    (1) Child Class(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) Child Class(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;
    

提交回复
热议问题