Какой правильный способ использовать requireJS с typescript?
Примеры, которые я нашел здесь и здесь говорят, чтобы использовать модуль (). Однако при компиляции я получаю "предупреждение TS7021:" Модуль (...) "устарел. Вместо этого используйте" require (...) ".
Итак, несколько основных вопросов:
- При использовании typescript и requireJS, как мне получить доступ к классу в одном
.ts из другого .ts файла, где requireJS будет загружать вторую
файл и дать мне класс в первом файле?
- Есть ли способ выполнить стандартный подход requireJS с двумя файлами .ts, где define() в верхней части загружает второй файл ts и возвращает обратно объект, который он строит в конце?
- Сортировка того же вопроса, что и вопрос № 2. Из файла java script я могу использовать конструкцию define() в файле type script, чтобы получить экземпляр объекта? Если да, то как?
Обновление: Ниже приведена компиляция tsc:
///<reference path='../../libs/ExtJS-4.2.0.d.ts' />
///<reference path='../../libs/require.d.ts' />
import fdm = require("./file-definitions");
require(["../../scripts/ribbon"], function () {
export module Menu {
export class MainMenu {
Ответы
Ответ 1
Я бы прокомментировал ответ Дэвида на ответ basarat (относительно модулей и классов), но у меня нет репутации. Я знаю, что этот вопрос устарел, но я не нашел ответа в другом месте.
Мне удалось использовать видео в basarat в сочетании с некоторыми другими ресурсами, чтобы понять это для таких классов, как David Thielen. Обратите внимание, что у меня больше нет записей для исходных файлов ts, но у меня есть amd-зависимые и импортные инструкции. В Eclipse с плагином TS palantir мой код и возможность перехода от использования к определению работают только с операторами amd-dependency и import. Файлы заголовков по-прежнему нужны, поскольку они не имеют никакого отношения к развертыванию и используются только компилятором TS. Также обратите внимание, что расширения файлов .ts используются для ссылочных операторов, но не для операторов amd и import.
В Utils.ts у меня есть:
///<reference path="headers/require.d.ts" />
export function getTime(){
var now = new Date();
return now.getHours()+":"+now.getMinutes()+':'+now.getSeconds();
}
В OntologyRenderScaler у меня есть:
///<reference path="headers/require.d.ts" />
///<reference path="headers/d3.d.ts" />
///<reference path="headers/jquery.d.ts" />
///<amd-dependency path="Utils" />
import Utils = require('./Utils');
export class OntologyRenderScaler {
...
Utils.getTime();
...
}
В OntologyMappingOverview.ts у меня есть:
///<reference path="headers/require.d.ts" />
///<reference path="headers/d3.d.ts" />
///<reference path="headers/jquery.d.ts" />
///<amd-dependency path="Utils" />
///<amd-dependency path="OntologyGraph" />
///<amd-dependency path="OntologyFilterSliders" />
///<amd-dependency path="FetchFromApi" />
///<amd-dependency path="OntologyRenderScaler" />
///<amd-dependency path="GraphView" />
///<amd-dependency path="JQueryExtension" />
import Utils = require('./Utils');
import OntologyGraph = require('./OntologyGraph');
import OntologyRenderScaler = require('./OntologyRenderScaler');
import OntologyFilterSliders = require('./OntologyFilterSliders');
import GraphView = require('./GraphView');
export class OntologyMappingOverview extends GraphView.BaseGraphView implements GraphView.GraphView {
ontologyGraph: OntologyGraph.OntologyGraph;
renderScaler: OntologyRenderScaler.OntologyRenderScaler;
filterSliders: OntologyFilterSliders.MappingRangeSliders;
...
this.renderScaler = new OntologyRenderScaler.OntologyRenderScaler(this.vis);
...
}
Я не справился (пока!), чтобы заставить вещи работать, как codeBelt, предложенные выше, но обмен, который мы имели в его блоге, показал, что если я заработаю его подход (с экспортом MyClass в нижней части файла), тогда Мне не нужно было бы удвоить импортированный идентификатор с именем класса. Я предполагаю, что он будет экспортировать класс интересов, а не пространство имен, в котором оно определено (неявный внешний модуль, т.е. Имя файла TypeScript).
Ответ 2
Для:
При использовании typescript и requireJS, как мне получить доступ к классу в одном .ts из другого .ts файла, где requireJS будет загружать вторую файл и дать мне класс в первом файле? Есть ли способ сделать стандартный метод requireJS с двумя файлами .ts, где define() at верхняя часть загружает второй ts файл и возвращает обратно объект, который он строит в конце?
просто:
// from file a.ts
export class Foo{
}
// from file b.ts
// import
import aFile = require('a')
// use:
var bar = new aFile.Foo();
и скомпилируйте оба файла с флагом --module amd
.
Для:
Сортировка того же вопроса, что и вопрос № 2. Из файла java script я могу использовать конструкцию define() в файле типа script, чтобы получить экземпляр объект? Если да, то как?
Чтобы просто использовать a.ts от b.js:
// import as a dependency:
define(["require", "exports", 'a'], function(require, exports, aFile) {
// use:
var bar = new aFile.Foo();
});
Это похоже на то, что вы получите, если вы скомпилируете b.ts
Ответ 3
Вы хотите, чтобы инструкция экспорта была ниже класса, который вы создаете.
// Base.ts
class Base {
constructor() {
}
public createChildren():void {
}
}
export = Base;
Затем, чтобы импортировать и использовать в другой класс, вы должны:
// TestApp.ts
import Base = require("view/Base");
class TestApp extends Base {
private _title:string = 'TypeScript AMD Boilerplate';
constructor() {
super();
}
public createChildren():void {
}
}
export = TestApp;
Вы можете проверить пример кода на http://www.codebelt.com/typescript/typescript-internal-and-external-modules/
Ответ 4
Я играл с typescript, пытаясь интегрировать его в наш существующий проект javascript/requirejs.
В качестве установки у меня есть Visual Studio 2013 с Typescript для vs v 0.9.1.1. Typescript настраивается (в visual studio) для компиляции модулей в формате amd.
Это то, что я нашел для меня работами (возможно, лучший способ, конечно)
- Использовать amd-зависимость, чтобы сообщить компилятору Typescript, добавить необходимый модуль в список компонентов, которые должны быть загружены
- В конструкторе экспортируемого класса используйте requirejss require функцию для фактического извлечения импортированного модуля (на этом этапе это синхронно из-за предыдущего шага). Для этого необходимо ссылка require.d.ts
В качестве побочного примечания, но поскольку это, на мой взгляд, важно для typescript, и потому, что это дало мне немного головную боль, в примере я показываю два способа экспорта классов, которые используют интерфейсы. Проблема с интерфейсами заключается в том, что они используются для проверки типов, но они не производят никакого реального вывода (сгенерированный .js файл пуст), и это вызывает проблемы типа "экспорт частного класса",
Я нашел два способа экспорта классов, которые реализуют интерфейс:
- Просто добавьте amd-зависимость к интерфейсу (как в файле Logger.ts)
И экспортируйте типизированную переменную, содержащую новый экземпляр класса
Экспортированный класс можно использовать напрямую (например, myClass.log( "привет" );
- Не добавляйте amd-зависимость к интерфейсу (как в файле Import.ts)
И экспортируйте функцию (например, Instantiate()), которая возвращает переменную типа, содержащую новый экземпляр класса
Экспортируемый класс может быть использован через эту функцию (т.е. myClass.instantiate(). Log ('hello))
Кажется, что первый вариант лучше: вам не нужно вызывать функцию создания экземпляра, плюс вы получите типизированный класс для работы. Недостатком является то, что файл javascript [empty] интерфейса перемещается в браузер (но его кэширование там в любом случае, и, возможно, вы даже используете минификацию, и в этом случае это вообще не имеет значения).
В следующих блоках кода есть 2 Typescript модуля, загруженные с требованием (amd): Logger и Import.
Файл ILogger.ts
interface ILogger {
log(what: string): void;
}
Файл Logger.ts
///<reference path="./ILogger.ts"/>
//this dependency required, otherwise compiler complaints of private type being exported
///<amd-dependency path="./ILogger"/>
class Logger implements ILogger {
formatOutput = function (text) {
return new Date() + '.' + new Date().getMilliseconds() + ': ' + text;
};
log = function (what) {
try {
window.console.log(this.formatOutput(what));
} catch (e) {
;
}
};
}
//this approach requires the amd-dependency above for the interafce
var exportLogger: ILogger = new Logger();
export = exportLogger;
Использование Logger.ts в другом файле ts (Import.ts)
///<reference path="../../../ext/definitions/require.d.ts"/>
///<amd-dependency path="Shared/Logger"/>
///<amd-dependency path="./IImport"/>
class _Import implements IImport{
ko: any;
loggerClass: ILogger;
constructor() {
this.ko = require('knockout');//require coming from require.d.ts (in external_references.ts)
this.loggerClass = require('Shared/Logger');
}
init(vm: any) {
this.loggerClass.log('UMF import instantiated...');
}
}
////Alternative Approach:
////this approach does not require adding ///<amd-dependency path="./IImport"/>
////this can be consumed as <imported_module_name>.instantiate().init();
//export function instantiate() {
// var r : any = new _Import();// :any required to get around the private type export error
// return r;
//}
//this module can be consumed as <imported_module_name>.init();
var exported: IImport = new _Import();
export = exported;
Файл IImport.ts
interface IImport {
init(vm: any): void;
}
Чтобы использовать модуль импорта прямо из javascript, используйте что-то вроде (извините, я не пробовал этот, но он должен работать)
define (['Import'], function (import)
{
//approach 1
import.init();
////approach 2
//import.instantiate().init();
});