TypeScript中的内部模块和外部模块有什么区别?

我花了一些时间阅读Typescript语言规范,并对内部和外部模块之间的差异感到有些困惑。 这是直接来自规范的描述:

内部模块(第9.2.2节)是其他模块(包括全局模块和外部模块)的本地或导出成员。 内部模块使用指定其名称和主体的ModuleDeclarations进行声明。 具有多个标识符的名称路径等效于一系列嵌套的内部模块声明。

外部模块(第9.4节)是使用外部模块名称引用的单独加载的代码体。 外部模块被编写为一个单独的源文件,其中至少包含一个导入或导出声明。 另外,可以使用全局模块中的AmbientModuleDeclarations声明外部模块,该声明直接将外部模块名称指定为字符串文字。 这将在第0节中进一步描述。

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

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

Valentin asked 2020-08-11T11:26:00Z
3个解决方案
26 votes

规范的9.3和9.4节对此进行了更清晰的说明。 我将在此重现这些部分中给出的一些示例。

外部模块

假设以下代码在main.ts中。

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

该文件引用外部模块module,该模块由module导出的内容定义。

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

请注意,module不在任何地方使用module关键字。 它只输出export

内部模块

该文件具有两个内部模块module

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块中。

Peter Olson answered 2020-08-11T11:26:37Z
7 votes

根据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流中定义的时间比方法调用晚。 使用外部模块,仅在方法调用时实例化引用的类。

Endre Simo answered 2020-08-11T11:27:12Z
1 votes

内部模块:

  1. 您可以在打字稿文件中定义模块。
  2. 在模块内定义的所有变量都将作用域限定在模块内,并从全局作用域中删除。
  3. 编译打字稿文件时,模块将转换为变量,这些变量根据需要嵌套以形成类似名称空间的对象。 请注意,使用IIFE(立即调用函数表达式)将模块内定义的类完全隔离。
  4. 下面的代码显示MyClass变量的作用域为MyInternalModule模块。 无法在模块外部访问它们,这就是为什么代码的最后一行显示错误无法找到名称MyClass的原因。
  5. 您可以使用export关键字在模块外部访问变量。
  6. 您还可以扩展内部模块,在文件之间共享它们以及使用三斜杠语法引用它们。(///)

例:

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

Typescript的编译版本:

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 = {}));

外部模块:

例:

// 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);
    }
}
vsjondhale answered 2020-08-11T11:28:17Z
translate from https://stackoverflow.com:/questions/12841557/whats-the-difference-between-internal-and-external-modules-in-typescript