I\'ve started work on a large-scale typescript project.
Right from the outset, I want to keep my files organized (this project will be split between lots of developers
Use re-exporting to create an external module that groups and exposes types from other modules:
// Classes/Animals.ts
export * from '.\Animals\Mammals';
export * from '.\Animals\Reptiles';
Then import the types from the new module as usual:
// app.ts
import * as Animals from '.\Classes\Animals'
let dog: Animals.Dog;
let snake: Animals.Snake;
Or
// app.ts
import { Dog, Snake } from '.\Classes\Animals'
let dog: Dog;
let snake: Snake;
Found a way to achieve your goal but not with the namespace keyword.
Sample Classes:
index.ts (as barrel)
animals.ts (for namespace grouping)
And here you go of the concept of the namespace.
External modules imply that you load modules file by file. Both AMD and CommonJS do not have such thing as namespace. You can use some kind of postprocessing to bundle files in one module.
The following defines an internal module:
module Animals {
export class Reptiles {
constructor() {
}
}
}
You shouldn't use import
for it. Animals.Reptiles
is visible anywhere. The only aim is to load scripts in the proper order (e.g. base classes before heritors). So you should list all files in ts.config
or somewhere else. In my project I use bundles on folders and have a convention to add @
to filenames of base classes.
Another solution is to use external modules: AMD (RequireJS) or CommonJS (Browserify). In that case remove upper level module
from declaration. If one file contains only one type you can export it as a root:
class Reptiles {
constructor() {
}
}
export = Reptiles;
You can refer module by file path:
import Reptilies = require('..\Animals\Reptilies')
var reptile = new Reptile();
Or with new ES6 modules:
export class Reptiles {
constructor() {
}
}
import { Reptiles } from '..\Animals\Reptilies';
Seems there is no way to do this using namespaces on their own (unless you want to use Module Augmentation and declare
every new item to add separately); however, a namespace can be part of a class, which can be extended! This is the best alternative I can find:
CoreLibraryTypes.ts
abstract class Types { }
namespace Types {
export class TypeA { }
export class TypeB { }
export class TypeC { }
}
export { Types };
CoreTypesExtended.ts
import CoreLibraryTypes from "./CoreLibraryTypes";
abstract class Types extends CoreLibraryTypes { }
namespace Types {
export class TypeD { }
export class TypeE { }
export class TypeF { }
}
export { Types };
The downside, of course, is that only the import of the second module will have the new types added. The first module will remain as before. Ideally it would be nice to "update" a namespace of types with additional types (like from plugins), such that module augmentation was more naturally supported (instead of having to write it by hand), but I guess that will have to do until someone realizes augmentation of modules by manually declaring updated definitions is just a half-a$$ way to do what namespaces already do lol (including classes, as seen above, which can already use namespace merging as part of the class). ;)
Note: In the example above I used export { Types };
for a reason - this will allow others to augment my modules. Augmentation is not supported for default exports (unless that is desired - sort of seals it virtually).
If you have your own library and you want to export the multiple files like from namespace, you can do this:
// index.ts
import * as Animals from './animals';
export { Animals };