如何将几个TypeScript模块包装到组中进行组织

Uza*_*jid 4 angularjs typescript

我的TypeScript项目已经成长为中等大小,我正在尝试提出一种很好的组织方式。

现在,该项目(一个Angular 1.x应用程序)具有以下结构:

-app/
 |
 |-components/
 | |
 | |-component A/
 | | |
 | | |-(..models..).ts
 | | |-(..services..).ts
 | |
 | |-component B/
 | | |
 | | |-(..models..).ts
 | | |-(..directives..).ts
 | |
 | (...)
 | |
 | |-component Z/
 | | |
 | | |-(..directives..).ts
 | | |-(..services..).ts
 | |
 | |-components.ts
 |
 |-app.ts
Run Code Online (Sandbox Code Playgroud)

基本上,我对应用程序组件进行了逻辑分组,例如,一个Video组件将在单个目录中声明其模型和服务。然后,我将所有组件加载到一个文件中,app/components.ts然后重新导出。

-app/
 |
 |-components/
 | |
 | |-component A/
 | | |
 | | |-(..models..).ts
 | | |-(..services..).ts
 | |
 | |-component B/
 | | |
 | | |-(..models..).ts
 | | |-(..directives..).ts
 | |
 | (...)
 | |
 | |-component Z/
 | | |
 | | |-(..directives..).ts
 | | |-(..services..).ts
 | |
 | |-components.ts
 |
 |-app.ts
Run Code Online (Sandbox Code Playgroud)

然后,我也将app/components.ts文件导入到每个组件中,因为几乎每次每次都需要多个组件,而分别导入每个组件将变得非常重复。

 // models
 export * from './componentA/models.ts';
 export * from './componentB/models.ts';
 export * from './componentC/models.ts';

 // services
 export * from './componentA/services.ts';
 export * from './componentX/services.ts';
 export * from './componentZ/services.ts';

 // directives
 export * from './componentB/directives.ts';
 export * from './componentY/directives.ts';
 export * from './componentZ/directives.ts';
Run Code Online (Sandbox Code Playgroud)

一段时间以来效果很好,但是现在由于该项目定义了几十个类和接口。ProjectName变得杂乱无章。

我想要的是根据不同成员将他们分组在一起。例如,如下结构:

 // app/components/componentA/services.ts
 import * as ProjectName from '../components.ts';

 export class ComponentA_Service1 extends ProjectName.BaseService {

     protected $http: ng.IHttpService;
     protected $log: ng.ILogService;
     protected configService: ProjectName.ConfigService;

     /** @ngInject */
     constructor($http: ng.IHttpService, $log: ng.ILogService, ConfigService: ProjectName.ConfigService) {

         this.$http = $http;
         this.$log = $lot;
         this.configService = ConfigService;
     }

     // (.....)
 }

 export class ComponentA_Service2 { /* ... */ }
 export class ComponentA_Service3 extends ProjectName.ComponentZ_Service4 { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

到目前为止,我还无法弄清楚如何使用TypeScript实现这一目标。更具体地说,我无法使用import多个不同的模块,而无法将export它们作为一个模块。

如果在TypeScript中甚至可以实现任何想法,或者我在这里朝着完全错误的方向前进?


更新(2016年1月31日):我认为我应该添加最终完成的工作。我已经开始尝试一种类似于下面@Vadim Macagon所建议的体系结构。虽然这是我想要做的正确解决方案,但由于@mk指出的原因,我最终决定反对它在下面接受的答案中。

我现在直接从每个文件的各自目录中导入各个模块。虽然在编写代码时肯定会花费一些时间,但它仍然是更好的方法。

Vad*_*gon 5

您已经熟悉重新导出,因此我相信这样应该可以:

// models.ts
export * from './componentA/models.ts';
export * from './componentB/models.ts';
export * from './componentC/models.ts';

// services.ts
export * from './componentA/services.ts';
export * from './componentX/services.ts';
export * from './componentZ/services.ts';

// directives.ts
export * from './componentB/directives.ts';
export * from './componentY/directives.ts';
export * from './componentZ/directives.ts';

// projectname.ts
import * as Models from './models';
import * as Services from './services';
import * as Directives from './directives';

export { Models, Services, Directives };

// app.ts
import { Models, Services, Directives } from './projectname';
// OR
import * as ProjectName from './projectname';
Run Code Online (Sandbox Code Playgroud)


mk.*_*mk. 2

以下是一些建议:

  1. 不要混合内部(命名空间)和外部模块,为整个项目选择一个并坚持使用。使用外部模块。除了声明合并之外,不要使用命名空间/内部。请参阅这篇文章和其他文章。
  2. 不要重新导出:它会使导航到原始文件变得更加麻烦,并且会破坏某些工具(例如查找用法)。它还创建对同一资源的两个引用 - 原始引用和重新导出引用。如果您的代码库调用其中一个文件中的副作用,这可能会掩盖副作用。

看起来您正在尝试最大程度地减少导入,但结果是您从一个全局“导入注册表”文件导入项目中的所有内容。庞大的定义可能适合某些组合良好的t.ds文件,但不适用于导入。相反,将模块视为文件,并根据需要单独导入它们:

import { MyClass } from "../foo/bar/MyClass";
import { toString, otherUtil } from "../foo/baz/Utils";
Run Code Online (Sandbox Code Playgroud)

换句话说,不要使用导入注册表文件,而是使用目录结构对文件/模块进行分组。这样做的一个小但好的结果是,您可以编写extends BaseService而不是总是限定,如extends ProjectName.BaseService. 如果您有太多导入(或太多导出),这表明该文件可能需要分解。