web-dev-qa-db-fra.com

Quelle est la bonne façon d'utiliser requireJS avec dactylographié?

Les exemples que j'ai trouvés ici et ici disent d'utiliser le module (). Cependant, lorsque je compile, j'obtiens "l'avertissement TS7021: 'module (...)' est obsolète. Utilisez plutôt 'require (...)'."

Donc, quelques questions de base:

  1. Lorsque j'utilise TypeScript et requireJS, comment puis-je accéder à une classe dans un fichier .ts à partir d'un autre fichier .ts où requireJS chargera le deuxième fichier et me donnera la classe dans le premier fichier?
  2. Existe-t-il un moyen de faire l'approche standard requireJS avec deux fichiers .ts où le define () en haut charge le deuxième fichier ts et retourne l'objet qu'il construit à la fin?
  3. Sorte de la même que la question # 2. À partir d'un fichier de script Java , puis-je utiliser la construction define () sur un type fichier de script pour obtenir l'objet instancié? Si c'est le cas, comment?

Mise à jour: Ce qui suit me donne une erreur de compilation 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 {
27
David Thielen

J'aurais commenté la réponse de David à la réponse de basarat (concernant les modules et les classes), mais je n'ai pas la réputation. Je sais que cette question est périmée, mais je n'ai pas trouvé de réponse ailleurs.

J'ai réussi en utilisant les vidéos de basarat, combinées à d'autres ressources, pour le comprendre pour des classes comme David Thielen avait besoin. Notez que je n'ai plus d'entrées pour mes fichiers source ts, mais j'ai des instructions d'importation et de dépendance AMD. Dans Eclipse avec le plugin TS de palantir, ma complétion de code et ma capacité à passer de l'utilisation à la définition fonctionnent uniquement avec les déclarations de dépendance et d'importation AMD. Les fichiers d'en-tête ont toujours besoin d'instructions car ils n'ont rien à voir avec le déploiement et ne sont utilisés que par le compilateur TS. Notez également que les extensions de fichier .ts sont utilisées pour les instructions de référence, mais pas pour les instructions AMD et import.

Dans Utils.ts j'ai:

///<reference path="headers/require.d.ts" />

export function getTime(){
    var now = new Date();
    return now.getHours()+":"+now.getMinutes()+':'+now.getSeconds();
}

Dans OntologyRenderScaler, j'ai:

///<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();
...
}

Dans OntologyMappingOverview.ts, j'ai:

///<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);
...
}

Je n'ai pas réussi (encore!) À faire fonctionner les choses comme codeBelt suggéré ci-dessus, mais un échange que nous avons eu sur son blog a révélé que si je fais fonctionner son approche (avec l'exportation de MyClass au bas du fichier), alors je ne le ferais pas besoin de doubler l'identifiant importé avec le nom de classe. Je suppose qu'il exporterait la classe d'intérêt plutôt que l'espace de noms dans lequel il est défini (le module externe implicite, c'est-à-dire le nom du fichier TypeScript).

12
Eric

Pour :

Lorsque j'utilise TypeScript et requireJS, comment puis-je accéder à une classe dans un fichier .ts à partir d'un autre fichier .ts où requireJS chargera le deuxième fichier et me donnera la classe dans le premier fichier? Existe-t-il un moyen de faire l'approche standard requireJS avec deux fichiers .ts où le define () en haut charge le deuxième fichier ts et retourne l'objet qu'il construit à la fin?

simplement:

// from file a.ts
export class Foo{

}

// from file b.ts
// import 
import aFile = require('a')
// use: 
var bar = new aFile.Foo();

et compiler les deux fichiers avec --module AMD drapeau.

Pour :

Sorte de la même que la question # 2. À partir d'un fichier de script Java, puis-je utiliser la construction define () sur un fichier de script de type pour obtenir l'objet instancié? Si oui, comment?

Pour utiliser a.ts de b.js simplement:

// import as a dependency:
define(["require", "exports", 'a'], function(require, exports, aFile) {

    // use:
    var bar = new aFile.Foo();
});

Ceci est similaire à ce que vous obtiendriez si vous compiliez b.ts

6
basarat

Vous souhaitez que l'instruction d'exportation se trouve sous la classe que vous créez.

// Base.ts
class Base {

    constructor() {
    }

    public createChildren():void {

    }
}

export = Base;

Ensuite, pour importer et utiliser dans une autre classe, vous feriez:

// TestApp.ts
import Base = require("view/Base");

class TestApp extends Base {

    private _title:string = 'TypeScript AMD Boilerplate';

    constructor() {
        super();
    }

    public createChildren():void {

    }
}

export = TestApp;

Vous pouvez consulter un exemple de code sur http://www.codebelt.com/TypeScript/typescript-internal-and-external-modules/

4
codeBelt

J'ai joué avec TypeScript, essayant de l'intégrer dans notre projet javascript/requirejs existant. Comme configuration, j'ai Visual Studio 2013 avec TypeScript pour vs v 0.9.1.1. TypeScript est configuré (dans Visual Studio) pour compiler des modules au format AMD.

C'est ce que j'ai trouvé pour moi (il y a peut-être une meilleure façon bien sûr)

  1. tiliser la dépendance AMD pour indiquer au compilateur TypeScript ajoute le module requis à la liste des composants qui doivent être chargés
  2. Dans le constructeur de la classe exportée, utilisez la fonction require de requirejs pour récupérer réellement le module importé (à ce stade, c'est synchrone en raison de l'étape précédente). Pour ce faire, vous devez référence require.d.ts

En remarque, mais comme c'est à mon avis essentiel pour TypeScript, et parce que cela m'a donné un peu mal à la tête, dans l'exemple, je montre deux façons d'exporter des classes qui utilisent des interfaces. Le problème avec les interfaces est qu'elles sont utilisées pour la vérification de type, mais elles ne produisent aucune sortie réelle (le fichier .js généré est vide), et cela cause des problèmes de type "exportation d'une classe privée". J'ai trouvé 2 façons de exporter des classes qui implémentent une interface:

  1. Ajoutez simplement une dépendance AMD à l'interface (comme dans le fichier Logger.ts) et exportez une variable typée contenant une nouvelle instance de la classe La classe exportée peut être consommée directement (ie myClass.log (‘hello’));
  2. N'ajoutez pas la dépendance AMD à l'interface (comme c'est le cas dans le fichier Import.ts) Et exportez une fonction (ie Instantiate ()) qui retourne une variable de type any contenant une nouvelle instance de la classe La classe exportée peut être consommé via cette fonction (ie myClass.instantiate (). log ('hello'))

Il semble que la première option soit meilleure: vous n'avez pas besoin d'appeler la fonction d'instanciation, et vous obtenez une classe typée avec laquelle travailler. L'inconvénient est que le fichier javascript de l'interface [vide] se déplace vers le navigateur (mais il y est quand même mis en cache, et peut-être que vous utilisez même la minification, auquel cas cela n'a pas d'importance du tout).

Dans les blocs de code suivants, il y a 2 modules TypeScript chargés avec require (AMD): Logger et Import.

Fichier ILogger.ts

interface ILogger {
    log(what: string): void;
}

Fichier 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;

Utilisation de Logger.ts dans un autre fichier 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;

Fichier IImport.ts

interface IImport {
    init(vm: any): void;
}

Pour consommer le module d'importation directement à partir de javascript, utilisez quelque chose comme (désolé, je n'ai pas essayé celui-ci, mais cela devrait fonctionner)

define (['Import'], function (import)
{
    //approach 1
    import.init();

    ////approach 2
    //import.instantiate().init();
});
2
Leo