TypeScript: расширить класс, который был загружен через требование

Контекст

Мы разбиваем наш текущий проект (TypeScript + RequireJS) на отдельные модули (ядро, виджет1, ...). Мы используем TypeScript версии 0.8.1.1.

Каждый модуль собирается в один файл, и изначально загружается ядро. Виджеты будут загружаться лениво, только в случае необходимости, но я хочу убедиться, что виджеты могут ссылаться на мои основные модули (но не включать модуль в свои выходные данные).


Для пояснения при компиляции модулей TypeScript в модули AMD операторы import будут скомпилированы в массив зависимостей функции define модуля. Пример:

Машинопись

import coreModule = module("core");

Вывод JavaScript (с флагом AMD)

define(['require', 'exports', 'core'], function(require, exports, __CoreModule__){
    var coreModule = __CoreModule__;
});

Это именно то, чего я пытаюсь избежать.

Поэтому я планирую заменить все операторы import someCoreModule = module("core/..."); на операторы var someCoreModule = require("core/...");.

Проблема

Проблема, с которой я сталкиваюсь, заключается в том, что некоторые из этих основных модулей возвращают базовые классы, которые могут быть расширены с помощью виджетов. Из-за пространства имен в TypeScript это означает, что мне нужно расширить их следующим образом:

import baseClass = module("core/SomeBaseClass");
class Child extends baseClass.Base {
}

И, конечно, мне все еще нужен тот же синтаксис при замене оператора import оператором require:

var baseClass = require("core/SomeBaseClass");
class Child extends baseClass.Base {
}

Это, очевидно, приводит к ошибке относительно отсутствующего типа (Base). В настоящее время я планирую обойти эту ошибку, предоставив заглушку реализации базового класса. Следующее:

declare module baseClass {
    class Base {
    }
}

var baseClass = require("core/SomeBaseClass");
class Child extends baseClass.Base {
}

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

Кто-нибудь знает лучшее решение или я вынужден решать свою проблему таким образом?

Как всегда, любая помощь приветствуется!


person thomaux    schedule 23.04.2013    source источник


Ответы (2)


Боюсь, нет способа заставить компилятор не генерировать дополнительное требование в вызове определения.

При использовании операторов vanilla require вы можете попытаться сгенерировать .d.ts из файла ts для вас (чтобы вам не нужно было добавлять эту заглушку), используя флаг компилятора --declaration. Надеюсь это поможет.

Также звучит как хорошая функция для компилятора (и простая для реализации, я полагаю), поэтому вы можете запросить это здесь: https://typescript.codeplex.com/workitem/list/basic (присылайте ссылку в комментарии, обязательно проголосую).

person basarat    schedule 23.04.2013
comment
Способ есть :) Используйте requireвместо import. Я собираюсь создать файлы d.ts для этих классов. Спасибо за ответ! - person thomaux; 24.04.2013
comment
Я голосую за то, чтобы закрыть вопрос, поскольку нашел правильное решение, как отделить свои виджеты от своего ядра (что и было идеей всего этого). Я не уверен, что это должно работать даже в TypeScript (как я описал). Спасибо за ваш вклад в любом случае :) - person thomaux; 24.04.2013
comment
@Anzeo, вы должны опубликовать свое решение и отметить его как ответ. Это совершенно верная вещь для stackoverflow. Вам придется подождать 2 дня после публикации ответа, прежде чем вы сможете это сделать. - person basarat; 24.04.2013
comment
Я знаю, но в этом случае мое решение не имеет ни малейшего отношения к этому вопросу :/ - person thomaux; 24.04.2013

Неверный ответ. Слева для контекста.

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

Когда вы делаете:

import baseClass = module("core/SomeBaseClass");

и скомпилируйте с флагом компилятора --module 'amd', он создает вызовы define и require так же, как вы пытаетесь достичь. Это не тянет его. Вы можете увидеть образец, который я создал здесь: https://github.com/basarat/TypeScriptEditor/tree/gh-pages/scripts

person basarat    schedule 23.04.2013
comment
В вашем примере скомпилированный CompilationService.js делает именно то, чего я пытаюсь избежать :) Он компилирует импорт EditorPosition внутри массива зависимостей вызова определения? - person thomaux; 23.04.2013
comment
Я думал, вы пытаетесь избежать проблемы с /// ‹ссылочным стилем ввода всего файла. Любая причина, по которой вы не хотите, чтобы это было в основном вызове определения? Ленивая загрузка? - person basarat; 23.04.2013
comment
Да, действительно, я хочу загружать файлы только тогда, когда они нужны :) - person thomaux; 23.04.2013