Reputation: 4283
Say I want to have one class per .ts file. I have two .ts files, that look like so:
export module MyClasses { export class A {} }
and
export module MyClasses { export class B {} }
I can't do this:
import MyClasses = module('A');
import MyClasses = module('B');
How do I define classes in separate files and put them into the same "namespace"? Furthermore, we end up having to do something like:
MyClasses.MyClasses.A
instead of
MyClasses.A
What's the point of this additional level of hierarchy? So that you can have more than one exported module in a module file? The best solution I've figure out so far is to remove "export module" (since "export class" seems to be sufficient when compiling AMD), which moves the class up one hierarchical level. Then:
import AModule = module('A');
module MyClasses{ var A = AModule.A; }
import BModule = module('B');
module MyClasses { var B = BModule.B; }
Though it works perfectly, it's not exactly succinct. Is there not a better way to do this?
Upvotes: 23
Views: 11575
Reputation: 2328
Unfortunately there does not seem to be a perfect solution but this is how I solved it for now:
File 'Controllers/MainController.ts':
class MainController {
...
}
export = MainController;
File 'Controllers/SecondController.ts':
class SecondController {
...
}
export = SecondController;
File 'Controllers/Namespace.ts':
import MainController = require('./MainController');
import SecondController = require('./SecondController');
export = { MainController, SecondController }
File 'App.ts' (where the 'namespace' is used)
import Controllers = require('Controllers/Namespace');
angular.module('app', [])
.controller('MainController', Controllers.MainController)
.controller('SecondController', Controllers.SecondController)
This gives you nice intellisense, hides the 400 import statements away and keeps the code where the namespace is actually used pretty clean...
Upvotes: 10
Reputation: 8074
I don't think there is a better way to achieve this with external modules. The language specification defines external modules as follows:
External modules (section 9.4) are separately loaded bodies of code referenced using external module names. An external module is written as a separate source file that contains at least one import or export declaration.
Further down it says that internal modules are open ended and can extend over multiple files:
Internal modules are “open-ended” and internal module declarations with the same qualified name relative to a common root (as defined in section 2.2) contribute to a single module.
I found no other mentioning of a similar statement for external modules. I'm pretty much convinced it's not. If you need module loading, then you'll have to live with reference paths to access types loaded from different files.
However, for me it sounds like you'd better go for internal modules. Then you can simply spread your module over two files
export module MyClasses { export class A {} }
and
export module MyClasses { export class B {} }
bring them into scope with reference paths
///<reference path='A.ts'/>
///<reference path='B.ts'/>
and then simply reference them with the module name such as e.g.
var a = new MyClasses.A();
Upvotes: 3
Reputation: 250842
Excuse the poor variable names, I was testing this in Visual Studio. It worked for my when using different names for the import statements.
import x = module('A');
import y = module('B');
x.MyClasses.A;
y.MyClasses.B;
Alternatively, you can use reference comments to a similar effect, but this is better if you are bundling, not if you are using module loading. You would need to drop the export
keyword from your two MyClasses
declarations:
///<reference path='A.ts'/>
///<reference path='B.ts'/>
var x = MyClasses.A;
Upvotes: 1