Подтвердить что ты не робот

Как вы помещаете несколько внешних модулей в одно и то же пространство имен в TypeScript?

Скажем, я хочу иметь один класс для каждого файла .ts. У меня есть два файла .ts, которые выглядят так:

export module MyClasses { export class A {} }

и

export module MyClasses { export class B {} }

Я не могу этого сделать:

import MyClasses = module('A');
import MyClasses = module('B');

Как определить классы в отдельных файлах и поместить их в одно и то же "пространство имен"? Кроме того, нам приходится делать что-то вроде:

MyClasses.MyClasses.A

вместо

MyClasses.A

Какова точка этого дополнительного уровня иерархии? Чтобы вы могли иметь более одного экспортированного модуля в файле модуля? Лучшим решением, которое я выяснил до сих пор, является удаление "модуля экспорта" (поскольку "класс экспорта", по-видимому, достаточен при компиляции AMD), который перемещает класс на один иерархический уровень. Тогда:

import AModule = module('A');
module MyClasses{ var A = AModule.A; }
import BModule = module('B');
module MyClasses { var B = BModule.B; }

Хотя он работает отлично, он не совсем лаконичен. Нет ли лучшего способа сделать это?

4b9b3361

Ответ 1

К сожалению, похоже, что это не идеальное решение, но я решил это сейчас:

File 'Controllers/MainController.ts':

class MainController {
    ...
}

export = MainController;

Контроллеры файлов /SecondController.ts ':

class SecondController {
    ...
}

export = SecondController;

Файл 'Контроллеры/Namespace.ts':

import MainController = require('./MainController');
import SecondController = require('./SecondController');

export = { MainController, SecondController }

Файл "App.ts" (где используется "пространство имен" )

import Controllers = require('Controllers/Namespace');

angular.module('app', [])
    .controller('MainController', Controllers.MainController)
    .controller('SecondController', Controllers.SecondController)

Это дает вам приятный intellisense, скрывает 400 заявлений импорта и сохраняет код, в котором пространство имен фактически используется довольно чисто...

Ответ 2

Я не думаю, что есть лучший способ добиться этого с помощью внешних модулей. Спецификация языка определяет внешние модули следующим образом:

Внешние модули (раздел 9.4) представляют собой отдельно загруженные тела кода, на которые ссылаются имена внешних модулей. Внешний модуль записывается как отдельный исходный файл, содержащий хотя бы одно объявление импорта или экспорта.

Далее в нем говорится, что внутренние модули открыты и могут распространяться на несколько файлов:

Внутренние модули являются "открытыми" и внутренними декларациями модулей с таким же квалифицированным именем по отношению к общему корню (как определено в разделе 2.2) вносят вклад в единый модуль.

Я не нашел другого упоминания о подобном утверждении для внешних модулей. Я почти уверен, что нет. Если вам нужна загрузка модуля, вам придется жить со ссылочными путями для доступа к типам, загружаемым из разных файлов.

Однако для меня звучит так, что вам лучше пойти на внутренние модули. Затем вы можете просто разложить свой модуль на два файла

export module MyClasses { export class A {} }

и

export module MyClasses { export class B {} }

вывести их в область видимости с помощью ссылок

///<reference path='A.ts'/>
///<reference path='B.ts'/>

а затем просто ссылайтесь на них с именем модуля, например,

var a = new MyClasses.A();

Ответ 3

Извините имена бедных переменных, я тестировал это в Visual Studio. Он работал у меня при использовании разных имен для операторов импорта.

import x = module('A');
import y = module('B');

x.MyClasses.A;
y.MyClasses.B;

В качестве альтернативы вы можете использовать ссылки на аналогичный эффект, но это лучше, если вы связываете, а не при загрузке модуля. Вам нужно будет отбросить ключевое слово export из двух объявлений MyClasses:

///<reference path='A.ts'/>
///<reference path='B.ts'/>

var x = MyClasses.A;