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

Какой правильный способ использовать 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 {
4b9b3361

Ответ 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();
});