My TypeScript project has grown in to a moderate size and I'm trying to come up with a good way to organize it.
Right now, the project (an Angular 1.x app) is has the following structure:
-app/
|
|-components/
| |
| |-component A/
| | |
| | |-(..models..).ts
| | |-(..services..).ts
| |
| |-component B/
| | |
| | |-(..models..).ts
| | |-(..directives..).ts
| |
| (...)
| |
| |-component Z/
| | |
| | |-(..directives..).ts
| | |-(..services..).ts
| |
| |-components.ts
|
|-app.ts
Basically, I've grouped app components logically so for instance a Video
component will have its models and services declared in a single directory. I then load import all the components into a single file app/components.ts
and re-export them.
// 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';
I'd then import the app/components.ts
file in each of the component as well, since I almost always required multiple components in every time and importing each one individually would get very repetitive.
// 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 { /* ... */ }
This worked out well for a while, but now since the project has several dozen classes and interfaces defined. ProjectName
becomes cluttered with dozens of members.
What I'd like is to group together different members based on what they are. For instance, a structure like:
namespace ProjectName {
namespace Models {
class ComponentA_Model1 { /* ... */ }
class ComponentA_Model2 { /* ... */ }
class ComponentB_Model1 { /* ... */ }
}
namespace Services {
class ComponentA_Service1 { /* ... */ }
class ComponentA_Service2 { /* ... */ }
class ComponentZ_Service4 { /* ... */ }
}
namespace Directives {
class ComponentB_Directive1 { /* ... */ }
class ComponentY_Directive2 { /* ... */ }
class ComponentZ_Directive3 { /* ... */ }
}
}
So far, I'm unable to figure out how to achieve that using TypeScript. More specifically, I'm unable to import
several different modules and export
them a single module.
Any ideas if it is even possible in TypeScript, or I'm heading in a completely wrong direction here?
Update (January 31, 2016): I thought I should add what I eventually ended up doing. I had already started trying an architecture similar to what was suggested by @Vadim Macagon below. While it is the correct solution for what I was looking to do, I ultimately decided against it because of the reasons pointed out by @mk. in the accepted answer below.
I'm now importing individual modules from their respective directories directly in each file. While it is certainly a slight overhead when writing code, it is still the better approach.
You're already familiar with re-exporting, so I believe something like this should work:
// 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';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With