¿Cómo se colocan múltiples módulos externos en el mismo espacio de nombres en TypeScript?
Digamos que quiero tener una clase por archivo .ts. Tengo dos archivos .ts, que se ven así:
export module MyClasses { export class A {} }
y
export module MyClasses { export class B {} }
No puedo hacer esto:
import MyClasses = module('A');
import MyClasses = module('B');
¿Cómo defino clases en archivos separados y las pongo en el mismo "espacio de nombres"? Además, terminamos teniendo que hacer algo como:
MyClasses.MyClasses.A
en lugar de
MyClasses.A
¿Cuál es el objetivo de este nivel adicional de jerarquía? ¿Para que puedas tener más de un módulo exportado en un archivo de módulo? La mejor solución que he encontrado hasta ahora es eliminar "export module" (ya que "export class" parece ser suficiente al compilar AMD), lo que mueve la clase un nivel jerárquico hacia arriba. Entonces:
import AModule = module('A');
module MyClasses{ var A = AModule.A; }
import BModule = module('B');
module MyClasses { var B = BModule.B; }
Aunque funciona perfectamente, no es exactamente conciso. ¿No hay una mejor manera de hacer esto?
Respuesta #1
Desafortunadamente, no parece haber una solución perfecta, pero así es como lo resolví por ahora:
Archivo 'Controllers/MainController.ts':
class MainController {
...
}
export = MainController;
Archivo 'Controllers/SecondController.ts':
class SecondController {
...
}
export = SecondController;
Archivo 'Controllers/Namespace.ts':
import MainController = require('./MainController');
import SecondController = require('./SecondController');
export = { MainController, SecondController }
Archivo 'App.ts' (donde se usa el 'namespace')
import Controllers = require('Controllers/Namespace');
angular.module('app', [])
.controller('MainController', Controllers.MainController)
.controller('SecondController', Controllers.SecondController)
Esto te da un buen intellisense, oculta las 400 declaraciones de importación y mantiene el código donde el espacio de nombres se usa realmente bastante limpio...
Respuesta #2
No creo que haya una mejor manera de lograr esto con módulos externos. La especificación del lenguaje define los módulos externos de la siguiente manera:
Los módulos externos (sección 9.4) son cuerpos de código cargados por separado que se referencian utilizando nombres de módulos externos. Un módulo externo se escribe como un archivo fuente separado que contiene al menos una declaración de importación o exportación.
Más abajo dice que los módulos internos son abiertos y pueden extenderse a varios archivos:
Los módulos internos son "abiertos" y las declaraciones de módulos internos con el mismo nombre calificado relativo a una raíz común (según se define en la sección 2.2) contribuyen a un único módulo.
No encontré ninguna otra mención de una declaración similar para módulos externos. Estoy bastante convencido de que no lo es. Si necesitas cargar módulos, entonces tendrás que aceptar rutas de referencia para acceder a los tipos cargados desde diferentes archivos.
Sin embargo, para mí suena como que sería mejor que uses módulos internos. Entonces puedes simplemente dividir tu módulo en dos archivos
export module MyClasses { export class A {} }
y
export module MyClasses { export class B {} }
traerlos al alcance con rutas de referencia
///<reference path='A.ts'/>
///<reference path='B.ts'/>
y luego simplemente hacer referencia a ellos con el nombre del módulo, por ejemplo.
var a = new MyClasses.A();
