Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript SystemJS中的类型脚本继承和循环依赖_Typescript_Ecmascript 6_Circular Dependency_Systemjs_Es6 Module Loader - Fatal编程技术网

Typescript SystemJS中的类型脚本继承和循环依赖

Typescript SystemJS中的类型脚本继承和循环依赖,typescript,ecmascript-6,circular-dependency,systemjs,es6-module-loader,Typescript,Ecmascript 6,Circular Dependency,Systemjs,Es6 Module Loader,在一个非常大的项目中,我将TypeScript与模块系统(SystemJS)一起使用。SystemJS支持循环依赖关系,大多数情况下它工作正常。然而,当涉及到类型脚本继承时,事情就开始破裂了 例如,如果a类依赖于B类,并且B类继承自a类,那么如果a类首先被加载: 它将暂停A类解析,并尝试加载B类依赖项 class B会认为它的依赖关系已经解决,因为已经触及了class A 类B的继承将无法解析,因为类A仍然未定义 我可以在web上找到的关于模块加载器循环依赖关系的大多数“解决方案”是: 将设计

在一个非常大的项目中,我将TypeScript与模块系统(SystemJS)一起使用。SystemJS支持循环依赖关系,大多数情况下它工作正常。然而,当涉及到类型脚本继承时,事情就开始破裂了

例如,如果
a类
依赖于
B类
,并且
B类
继承自
a类
,那么如果
a类
首先被加载:

  • 它将暂停
    A类
    解析,并尝试加载
    B类
    依赖项
  • class B
    会认为它的依赖关系已经解决,因为已经触及了
    class A
  • 类B的继承将无法解析,因为类A仍然未定义
  • 我可以在web上找到的关于模块加载器循环依赖关系的大多数“解决方案”是:

    • 将设计/组合类更改为单个模块
    • CommonJS和非类型脚本特定的解决方法
    <> P>我觉得对于循环设计有有效的理由,把类合并成巨型文件并不总是令人满意的,所以请考虑这些解决方案对于我要问的问题来说是离题的。p>
    有什么解决实际问题的办法吗

    更改您的设计是最有利的解决方案。类不应该依赖于它的子类。如果您在工厂中使用它们,这是一个单独的问题,应该放在单独的类/函数/模块中

    有什么解决实际问题的办法吗


    正如您所说,只有在模块A首先加载时才会出现问题。解决方案是防止这种情况,并编写一个额外的模块,作为a及其所有子类的代理,同时以正确的顺序导入它们。

    在这种情况下,我建议您通过创建一个单独的接口
    I
    来删除
    a->B
    的依赖关系。
    A
    B
    都需要知道
    I
    ,而
    B
    需要实现它

    在加载过程中,
    B
    必须告诉
    A
    在哪里可以找到
    I
    的构造函数或工厂(由
    B
    实现)。这将留给您以下依赖项:

    A -> I
    B -> I
    B -> A
    
    接口
    I
    可能如下所示:

    interface I {
      bFoo(): void;
    }
    
    export default I;
    
    import I from "./i";
    
    class A {
      private static __ICtor : new() => I;
      public static setIConstructor(ctor: new() => I) {
        A.__ICtor = ctor;
      }
    
      private __atSomePoint() : I {
        return new A.__ICtor();
      }
    }
    
    export default A;
    
    A类
    可能如下所示:

    interface I {
      bFoo(): void;
    }
    
    export default I;
    
    import I from "./i";
    
    class A {
      private static __ICtor : new() => I;
      public static setIConstructor(ctor: new() => I) {
        A.__ICtor = ctor;
      }
    
      private __atSomePoint() : I {
        return new A.__ICtor();
      }
    }
    
    export default A;
    
    最后是B类

    import I from "./i";
    import A from "./a";
    
    class B extends A implements I {
      public bFoo() {}
    }
    
    A.setIConstructor(B);
    

    我想这会解决你的循环依赖,即使现在已经太晚了。

    这里有一个简单的方法可以通过使用Babel transform插件来解决这个问题:

    它所做的是将文件开始时的模块导入转换为内联要求,即仅在使用其他模块之前实际导入/需要其他模块

    在大多数情况下,这会自动解决问题,因为当任何使用代码的类实际运行时,模块都已完成导出


    请注意,默认情况下,上面的插件应用于项目中的所有导入,将它们全部转换为内联。然而,一个更严重的问题是,我找不到一种内置的方法使它能够与相对路径导入/需求一起工作

    我在这里的项目分支中解决了这两个问题:

    我提出了这些更改的请求,但它正在等待审查