对TypeScript模块感到困惑

Kri*_*fer 7 import namespaces module typescript

我是TypeScript的新手,但在C#中有一个背景,我对如何处理TypeScript模块有点困惑.我一直在考虑将模块作为C#中的命名空间,但这可能是错误的,因为我的代码行为不像我期望的那样.

我有以下文件夹结构:

|-myApp
|  |-myController
|  |      |-myController.ts
|  |-models
       |-a.ts
       |-b.ts
Run Code Online (Sandbox Code Playgroud)

而这段代码:

// a.ts
module MyApp.Models {
    export class A {

    }
}
// b.ts
module MyApp.Models {
    export class B {

    }
}

// myController.ts (THIS DOESN'T WORK)
module MyApp.MyController {
    import Models = MyApp.Models;
    class MyController {
        a = new Models.A();
        b = new Models.B();
    }
}

// myController.ts (THIS WORKS)
module MyApp.MyController {
    class MyController {
        a = new Models.A();
        b = new Models.B();
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我尝试导入模块(名称空间?)模型将导致运行时出错,因为模型未定义.但是,如果我删除import语句,代码将正常工作.我可能没有想清楚并且做了一些非常愚蠢的初学者错误但是有人可以告诉我我做错了什么以及在我的特定场景中使用模块的最佳方式是什么.如果我删除导入而不是导入它,为什么它可以工作?

关心Kristofer

Ole*_*uka 3

抱歉回复晚了。

模块/命名空间的问题和魔力发生在三件事上:

  1. 你的系统 - 由于你的系统 TypeScript 编译器通过不同的方式发现文件,当它将你的源代码编译为 JS 代码时,它会占据一个位置,因为相同的 ts 文件提供不同的 JS 结果。
  2. 理解魔法语句/// <reference path="***"/>。如果没有像 AMD 或 System.js 等额外的模块系统,那么使用这个词非常重要。因为如果你使用合并编译,它就会发生,因为它告诉编译器应该以什么顺序编译文件。
  3. 了解 TypeScript 在编译的 JS 文件中提出的 JS 执行和结构。考虑下一个例子 - (这是你编译成 JS 的例子)

        var MyApp;
        (//functon wrapping
         function (MyApp) {//function declaration 
            var MyController;
            (function (MyController_1) {
                var Models = MyApp.Models;
                var MyController = (function () {
                    function MyController() {
                        this.a = new Models.A();
                        this.b = new Models.B();
                    }
                    return MyController;
                })();
                MyController_1.MyController = MyController;
            })(MyController = MyApp.MyController || (MyApp.MyController = {}));
        }
        )(MyApp || (MyApp = {}));// end of function wrapping and it execution
        /// <reference path="myApp/MyController/myController.ts"/>
    
        new MyApp.MyController.MyController(); // createing new instance of MyController
    
        var MyApp;
        (function (MyApp) {
            var Models;
            (function (Models) {
                var B = (function () {
                    function B() {
                    }
                    return B;
                })();
                Models.B = B;
            })(Models = MyApp.Models || (MyApp.Models = {}));
        })(MyApp || (MyApp = {}));
        var MyApp;
        (function (MyApp) {
            var Models;
            (function (Models) {
                var A = (function () {
                    function A() {
                    }
                    return A;
                })();
                Models.A = A;
            })(Models = MyApp.Models || (MyApp.Models = {}));
        })(MyApp || (MyApp = {}));
        //# sourceMappingURL=app.js.map
    
    Run Code Online (Sandbox Code Playgroud)

    如果你深入研究 JS,你会发现 JS 代码是按照下一个顺序执行的

    • 读取函数并将其传递到内存中
    • 执行另一个代码

    这就是为什么下一个代码可以工作

     myFunction();
    
     function myFunctuion(){};
    
    Run Code Online (Sandbox Code Playgroud)

    由于 typescript JS 模块和类的构建技术,它使用如下匿名函数:

    var MyApp;
        (//functon wrapping
         function (MyApp) {//function declaration 
            var MyController;
            (function (MyController_1) {
                var Models = MyApp.Models;
                var MyController = (function () {
                    function MyController() {
                        this.a = new Models.A();
                        this.b = new Models.B();
                    }
                    return MyController;
                })();
                MyController_1.MyController = MyController;
            })(MyController = MyApp.MyController || (MyApp.MyController =  {}));
    
    Run Code Online (Sandbox Code Playgroud)

    在这种情况下,调用 next 会导致运行时异常,因为 anonimus 块之前尚未执行。

      MyController(); // here runtime exception
    
      var MyController = (function () {
                    function MyController() {
                        this.a = new Models.A();
                        this.b = new Models.B();
                    }
                    return MyController;
                })();
    
    Run Code Online (Sandbox Code Playgroud)

    现在,回到我们的示例并发现它,正如您所看到的 MyController 定义较早,而不是我们执行的匿名函数和名称为 MyController 的变量现在存在于全局范围中。下一步是执行 MyController 类的构造函数,在其中我们找到接下来的两部分代码

           this.a = new Models.A();
           this.b = new Models.B();
    
    Run Code Online (Sandbox Code Playgroud)

    Modules但是这里我们得到一个错误,因为由变量和类组成A的匿名函数 B尚未执行。这就是为什么此时我们收到变量 Modules 未定义的错误。

希望这个主题能让你更好地了解 JS 和 TS,并为你的新功能提供帮助!

祝你好运!

PS这是工作示例