对TypeScript模块感到困惑

时间:2015-09-26 17:57:57

标签: import module namespaces typescript

我是TypeScript的新手,但在C#中有背景,我对如何处理TypeScript模块感到有点困惑。我一直在考虑将模块作为C#中的命名空间,但这可能是错误的,因为我的代码没有按照我期望的方式运行。

我有以下文件夹结构:

|-myApp
|  |-myController
|  |      |-myController.ts
|  |-models
       |-a.ts
       |-b.ts

和这段代码:

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

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

关心Kristofer

2 个答案:

答案 0 :(得分:4)

对不起,迟到了。

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

  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
    

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

    • 阅读功能并将其传递到内存
    • 执行其他代码

    这就是下一个代码可以工作的原因

     myFunction();
    
     function myFunctuion(){};
    

    由于模型和类的打字稿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 =  {}));
    

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

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

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

           this.a = new Models.A();
           this.b = new Models.B();
    

    但是在这里我们得到一个错误,因为包含变量Modules和类AB的匿名函数尚未执行。这就是为什么在这一刻我们得到的变量模块未定义的错误。

  4. 希望这个主题让您更好地了解JS和TS,并帮助您使用新功能!!!

    祝你好运!

    P.S。 Here is working example

答案 1 :(得分:1)

Typescript模块类似于C#名称空间。他们帮助组织代码库。

import语句可用于两件事:提供别名或导入外部模块。

要创建别名,请按照以下方式使用导入:

import Models = App.Models;

要导入您使用的外部模块:

import Models = './path/to/module';

我无法弄清楚你的代码无法正常工作的原因。我试图在我的机器上重现它,但两个控制器都适合我。