8

我不知道是否有可能将“导出模块”分布在多个文件中。

如果我有文件 Contact.ts:

// file Contact.ts
export module Contacts {
   export class Contact {
      ...
   }
}

和另一个 ContactView.ts

// file ContactView.ts
export module Contacts {
   export class ContactView {
      model: Contact;  // <---  is not recognized
   }
}

然后 TSC 无法识别 Contact 类。如您所见,Contact 和 ContactView 被声明为驻留在同一个模块中,并且根据规范它应该可以工作。

我正在构建一个使用 require.js 和 AMD 模式的复合应用程序,所以我必须使用“导出模块”声明。

我应该做某种类型的“提前声明”还是一些棘手的“导入”?

感谢您的建议。

编辑:目前我通过导入分别加载每个模块,但是,如果您注意到,它会造成大量代码浪费和大量“导入”依赖项。我的问题是,是否有办法使用相同的命名空间(即联系人)来告知我不想导入的 TS。我正在研究正常的 // 命令,但它不起作用。我什至尝试了 *.d.ts 声明文件,但到目前为止没有成功。

4

2 回答 2

6

该规范允许您跨多个文件定义内部模块(本质上,内部模块是指 javascript 模块模式)。外部模块,例如 AMD 或 CommonJS 模块,认为每个文件都是实际的“代码模块”,并且其中的命名空间/命名是无关紧要的,因为模块无论如何都会被加载到它自己的新对象中。

您可以编写以下代码以在 ContactView.ts 模块中加载 Contact.ts 模块:

// file ContactView.ts    
import mod = module("./Contact");

export module Contacts {
   export class ContactView {
      model: mod.Contacts.Contact;  // <---  will be recognized
   }
}

这应该可以很好地工作,但是如果您想访问另一个区域中两个模块的内容(例如,自己创建一个新的 Contact 模型),您必须基本上导入它们:

import c = module("./Contact");
import cv = module("./ContactView");

我认为这已经足够好了,因为您清楚地说明了您的依赖关系。缺点是它们不会共享一个共同的父对象,因此让它们都处于“联系”模块模式中可能没有多大用处。

另一种选择是将“Contact”与“ContactView”一起导出,如下所示(授予此代码有点愚蠢,因为您已经通过 ContactView 的模型属性做到了这一点,但永远不会少......):

export module Contacts {
   export class ContactView {
       model: mod.Contacts.Contact;
       constructor() {
           this.model = new mod.Contacts.Contact();
       }
    }

    export var Contact = mod.Contacts.Contact;
}

因此,您可以在加载 ContactView 后访问它。

编辑:顺便说一句,您不仅可以通过“export module Name { ... }”导出模块,还可以导出任何内容,因为文件本身就是模块。所以你可以有一个只有“export function foo() { ... }”的文件,而没有任何模块模式代码包装它。

EDIT2:看起来 AMD 可能具有加载多个依赖项并从中构建“模块”的功能,但我不知道这在 TS 中如何工作,这里有一个链接:http: //www.adobe.com /devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html(构造器模块)。

于 2012-10-09T01:21:33.023 回答
4

我在同一个问题上挣扎了一段时间,只是想分享我在做什么,以防其他人在这个问题上徘徊。

首先,我为自己定义了一个引用文件,它声明了我的模块中的所有文件:

/// <reference path="_contacts.dependencies.ts" />
/// <reference path="../contacts/Contact.ts" />
/// <reference path="../contacts/ContactView.ts" />
/// <reference path="../contacts/ContactModel.ts" />

请注意,文件内指定的路径是相对于参考文件本身 ( _contacts.ts) 的位置,与参考.js文件不同。我的目录结构如下所示:

modules
    references // all of the reference files
        knockout 
        underscore
        // ... a subfolder for every 3rd party library used
    contacts
    commerce 
    // ... other modules at same level as contacts

回到参考文件本身。第一行包含一个单独的参考文件,其中列出了模块使用的所有外部库,例如下划线、moment 或您有.d.ts定义文件的任何其他现有库。其余行是组成模块的文件。

在作为模块一部分的每个文件中,我引用了上面的文件:

/// <reference path="../references/_contacts.ts" />
module Contacts {
    export class Contact { 
        public model: ContactModel;
        // ...
    }
} 

同样,您可以创建一个参考文件来列出所有模块:

/// <reference path="_address.ts" />
/// <reference path="_contacts.ts" />
/// <reference path="_commerce.ts" />

只需从您的源文件中指出这一点。

但是,这并不能解决发出的代码在单独的文件中的问题。对于这个问题,我使用了一个 JavaScript 缩小工具,它能够将多个文件捆绑到一个源文件中。根据您的编译设置和用例需求,您可能需要在生成的代码周围应用一些包装器,以使其作为 AMD 模块工作(还不太熟悉该部分)。

于 2012-12-12T23:12:09.423 回答