TypeScript:解决方案中的多个项目

vex*_*tor 10 typescript

我已经完成了在Visual Studio 2012中将一个JavaScript库移植到TypeScript.总共大约有60个类,每个类都在自己的.ts文件中定义.

所有类都在同一模块中定义.我使用引用注释来reder到其他文件中定义的类.每个文件的布局如下所示:

///<reference path='./../myotherclass.ts' />

module MyModule {

    export class MyClass {
        ...
    }

}
Run Code Online (Sandbox Code Playgroud)

现在我在同一个解决方案中创建了第二个项目,它将成为使用我新移植的库的实际应用程序.我必须以某种方式包括我的库,我想这就是模块系统的用途.但是,我不确定要导入哪些文件,因为MyModule分布在几十个文件中.这是我可以使用.d.ts文件吗?

此外,为了能够导入模块,必须使用'export'关键字声明它,但如果我这样做,则不再通过引用注释找到它.

最重要的是,应该编译这两个项目,以便编译器输出可以很容易地与像requireJS这样的模块加载器一起使用.

实现这一切的最佳方法是什么?

谢谢!

nxn*_*nxn 9

好吧,让我首先说"模块"可能意味着不同的东西.例如,存在"模块模式",即"MyModule"创建的模块模式.据我所知,TypeScript在语言规范中将它们称为"内部模块",这些与"外部模块"不同,您将使用RequireJS加载.主要区别在于外部模块希望拥有自己的隔离环境,并具有可用于导出其功能的预定义"导出"对象.

看一下模块的输出:

var MyModule;
(function (MyModule) {
    var MyClass = (function () {
        function MyClass() { }
        return MyClass;
    })();
    MyModule.MyClass = MyClass;    
})(MyModule || (MyModule = {}));
Run Code Online (Sandbox Code Playgroud)

您会看到它正在将内容导出到"MyModule"中,这些内容将全局提供给您加载的其他脚本文件,例如,html"script"块.由于你提到你有60个,你可能还可以设置编译器输出一个你可以包含在标记中的文件,而不是逐个加载每个文件.

继续,如果您将模块声明从"module MyModule {...}"更改为"export module MyModule {...}",请查看输出会发生什么:

(function (MyModule) {
    var MyClass = (function () {
        function MyClass() { }
        return MyClass;
    })();
    MyModule.MyClass = MyClass;    
})(exports.MyModule || (exports.MyModule = {}));
Run Code Online (Sandbox Code Playgroud)

如您所见,您的模块仍然使用"模块模式",但它被指定为"导出"的成员,表示它意味着要加载,例如,节点的"require"功能.

在这种情况下,您可能希望使用以下代码实际使用您的模块:

import wrapper = module("./MyModule");
var instance = new wrapper.MyModule.MyClass();
Run Code Online (Sandbox Code Playgroud)

请注意,"./ MyModule"名称实际上是指模块定义的文件名(减去.js扩展名)(这就是为什么VS说它找不到那些模块的原因).代码应该编译成类似的东西:

var wrapper = require("./MyModule");
var instance = new wrapper.MyModule.MyClass();
Run Code Online (Sandbox Code Playgroud)

要添加到此,您甚至不再需要使用"module"关键字执行任何操作来创建模块.你可以简单地导出一个函数:

// foo.ts
export function foo() {
    ...
};

// some other file in the same dir
import wrapper = module("./foo");
var result = wrapper.foo();
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为函数'foo'将直接分配给"exports",它将别名为另一个文件中的"wrapper".

为了进一步增加模块相关事物的混乱,我还应该提到AMD模块的不同之处还在于它们是异步加载的,这与节点的"require"不同.要让TypeScript输出那些你需要将"--module AMD"参数传递给编译器.

无论如何,我希望我能够很好地解释这种情况,以便你能够弄清楚你究竟需要/想要什么.您最终使用的模块类型将取决于您将如何使用它们...即节点,Web或两者的混合.