首页 文章

TypeScript中内部和外部模块之间的区别是什么?

提问于
浏览
40

我花了一些时间阅读Typescript语言规范,并对 internalexternal 模块之间的区别感到有些困惑 . 以下是直接从规范中进行的描述:

内部模块(第9.2.2节)是其他模块的本地或导出成员(包括全局模块和外部模块) . 使用指定其名称和正文的ModuleDeclarations声明内部模块 . 具有多个标识符的名称路径等同于一系列嵌套的内部模块声明 . 外部模块(第9.4节)是使用外部模块名称引用的单独加载的代码体 . 外部模块被编写为包含至少一个导入或导出声明的单独源文件 . 此外,可以使用全局模块中的AmbientModuleDeclarations声明外部模块,该模块直接将外部模块名称指定为字符串文字 . 这将在第0节中进一步描述 .

根据我的理解,我认为外部模块对应于打字稿文件,而不包含简单地导出一组类型和/或变量的模块定义 . 从另一个打字稿文件,我可以简单地导入 foo.ts 中的外部模块 import foo = module("foo");

有人可以向我解释外部和内部模块之间的意图吗?

3 回答

  • 6

    规范的第9.3和9.4节更清楚地解释了这一点 . 我将在这里重现这些部分给出的一些例子 .

    外部模块

    假设以下代码位于 main.ts 中 .

    import log = module("log");
    log.message("hello");
    

    此文件引用外部模块 log ,由 log.ts exports定义 .

    export function message(s: string) { 
      console.log(s); 
    }
    

    请注意 log.ts 在任何地方都不使用 module 关键字 . 它只是用 export 导出东西 .

    内部模块

    该文件有两个内部模块, X.Y.Z .

    module A.B.C { 
      import XYZ = X.Y.Z; 
      export function ping(x: number) { 
        if (x > 0) XYZ.pong(x – 1); 
      }
    } 
    module X.Y.Z { 
      import ABC = A.B.C; 
      export function pong(x: number) { 
        if (x > 0) ABC.ping(x – 1); 
      } 
    }
    

    这些(主要)表现为外部模块,但它们包含在一个文件中,您不必引用任何外部文件来使用它们 . 它们必须在定义时包含在 module 块中 .

  • 1

    根据Anders的演示文稿:http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript(34:40)和Typescript文档,外部模块是基于顶级AMD(异步模型定义)或CommonJS的模块 .

    外部模块在隐藏模块定义的内部语句并且仅显示与声明的变量关联的方法和参数的意义上是有用的 .

    假设您有一个 Main 类,其中定义的 log 方法放在 transfer.js 文件中 . 只有在导入源js文件顶部的 transfer.js 文件时, Main 类的内部方法才可见: ///<reference path="transfer.js"/> . 这样编译器就可以在运行时消除所有js文件的遍历 .

    这是使用外部模块的巨大好处 . 另一个是当您尝试引用外部方法或类时,该方法或类在方法调用之后定义正常的自顶向下javascript流 . 使用外部模块,引用的类仅在方法调用时实例化 .

  • 27

    Internal Module:

    • 您可以在typescritp文件中定义模块 .

    • 模块中定义的所有变量都作用于模块,并从全局范围中删除 .

    • 编译打字稿文件时,模块将转换为必要时嵌套的变量,以形成类似命名空间的对象 . 请注意,使用IIFE(立即调用的函数表达式)整齐地隔离模块中定义的类 .

    • 下面的代码显示MyClass变量作用于MyInternalModule模块 . 它们无法在模块外部访问,这就是为什么代码的最后一行显示错误无法找到名称MyClass .

    • 您可以使用export关键字访问模块外部的变量 .

    • 您还可以扩展内部模块,跨文件共享它们,并使用三斜杠语法引用它们 . (///)

    Example

    module MyInternalModule{  
        class MyClass{               //if We write export keyword before the MyClass then last line works fine
            constructor (
                public height: number, 
                public width: number) {
        }
        }                   
        //working properly
        var obj1 = new MyClass(10, 4);
    }
    
    // it wont work //Because the out of the scope
    var obj2 = new MyInternalModule.MyClass(10,4) //shows error: can not find name MyClass
    

    打字稿的编译版本:

    var MyInternalModule;
    (function (MyInternalModule) {
        var MyClass = (function () {
            function MyClass(height, width) {
                this.height = height;
                this.width = width;
            }
            return MyClass;
        })();
        //working properly
        var obj1 = new MyClass(10, 4);
    })(MyInternalModule || (MyInternalModule = {}));
    

    External Module:

    Example

    // bootstrapper.ts file
    
    // imports the greeter.ts file as the greeter module
    import gt = module('greeter');  
    export function run() {  
        var el = document.getElementById('content');
        var greeter = new gt.Greeter(el);
        greeter.start(); 
    }
    
    // greeter.ts file
    
    // exports the entire module
    export class Greeter {  
        start() {
             this.timerToken = setInterval(() => 
                 this.span.innerText = 
                 new Date().toUTCString(), 500);
        }
    }
    

相关问题