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

我花了一些时间阅读Typescript语言规范,对内部外部模块之间的区别有些困惑。 以下是从规范中直接得到的描述:

内部模块(第9.2.2节)是本地或其他模块的导出成员(包括全局模块和外部模块)。 内部模块使用ModuleDeclarations声明它们的名称和正文。 具有多个标识符的名称path相当于一系列嵌套的内部模块声明。

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

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

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

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

外部模块

假设下面的代码在main.ts

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

这个文件引用一个外部模块log ,由任何log.ts定义。

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

请注意, log.ts不会在任何地方使用module关键字。 它只是出口的东西export

内部模块

这个文件有两个内部模块, XYZ

 module ABC { import XYZ = XYZ; export function ping(x: number) { if (x > 0) XYZ.pong(x – 1); } } module XYZ { import ABC = ABC; export function pong(x: number) { if (x > 0) ABC.ping(x – 1); } } 

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

根据安德斯介绍: http ://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript(34:40)和Typescript文档,外部模块是基于顶级AMD(asynchronous模型定义)或CommonJS的。

外部模块在某种意义上是有用的,它们隐藏了模块定义的内部语句,只显示与声明variables相关的方法和参数。

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

这是使用外部模块的巨大好处。 另一个是当你试图引用一个外部的方法或类在正常的自顶向下的JavaScriptstream定义晚于方法调用。 使用外部模块,被引用的类仅在方法调用时被实例化。

内部模块:

  1. 你可以在你的typescritp文件中定义模块。
  2. 在模块中定义的所有variables都被限定在模块中并从全局范围中删除。
  3. 当你编译你的打字稿文件时,你的模块被转换成variables,这些variables可以根据需要进行嵌套,以形成名称空间对象。 请注意,使用IIFE(立即调用的函数expression式)将在模块内定义的类整齐地隔离开来。
  4. 下面的代码显示MyClassvariables的作用域为MyInternalModule模块。 他们不能被访问的模块之外,这就是为什么代码的最后一行显示错误找不到名称MyClass。
  5. 您可以使用export关键字访问模块外部的variables。
  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 

编译版本的脚本:

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