Typescript: Autoriser les définitions de module à être déclarées en tant que variables globales

Créé le 15 mai 2015  ·  11Commentaires  ·  Source: microsoft/TypeScript

J'ai le fichier de définition de type React (qui est déclaré à l'aide d'un module externe). Dans mes fichiers source, je fais généralement:

import * as R from "react"

et peut alors utiliser avec plaisir R.createElement(... etc d'une manière fortement typée. Je peux même faire:

let _r = R;
_r.createElement(...

Ce que je veux, c'est ne pas avoir à importer R dans chaque fichier, mais plutôt l'avoir comme déclaration globale (oui, je suis prêt à poluer l'espace de noms global avec quelques variables). J'ai essayé, dans un .d.ts :

import * as React from "react";
declare var R : React;

Cela ne fonctionne pas cependant, j'obtiens "Impossible de trouver le nom 'React'". Existe-t-il un autre moyen d'exporter l'ensemble du module en tant que global, sans avoir à modifier le sous-jacent react.d.ts?

Question

Commentaire le plus utile

Salut @Evertt en effet, je reçois aussi cette erreur maintenant. Au départ, mon code source n'utilisait pas la syntaxe du module ES6, mais une fois que j'ai refactoré certains fichiers avec cette syntaxe, j'ai eu la même erreur. J'ai fait des recherches et ce qui a fonctionné pour moi maintenant, c'est lorsque je crée un deuxième fichier globals.d.ts et que je le place également dans le dossier typings:

import * as _R from 'ramda';
import * as _mobx from 'mobx';

declare global {
  const R: typeof _R;
  const mobx: typeof _mobx;
}

En fait, ce fichier seul semble "satisfaire" le compilateur dactylographié, donc en théorie vous n'avez pas besoin des autres fichiers que j'ai mentionnés précédemment. Cependant, dans mon cas particulier (j'utilise WebStorm) lorsque je n'avais que le fichier globals.d.ts, mon IDE me demandait constamment d'importer les modules et les complétions sur ces globals étaient incomplètes. J'ai donc essentiellement gardé les deux fichiers dans le répertoire typings qui satisfait le typage et mon IDE. Pas vraiment sympa, mais pour les quelques globaux que l'on utilise généralement, je suppose que c'est correct de maintenir ces fichiers.

Voici mon tsconfig.json pour référence:

{
  "compilerOptions": {
    "target": "ES5",
    "module": "amd",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "lib": [
      "ES6",
      "DOM",
      "ScriptHost"
    ],
    "sourceMap": true,
    "strictNullChecks": true
  },
  "include": [
    "types/**/*",
    "src/**/*"
  ]
}

Je n'utilise pas Webpack ou quoi que ce soit à regrouper. Je transpile simplement les fichiers individuels et les charge via le système de modules https://github.com/SAP/openui5 (qui est similaire à AMD) et les associe pour la production uniquement.

La version Typecript est: 2.2.1

J'espère que ça t'as aidé.

Tous les 11 commentaires

Ce n'est pas possible car dès que vous ajoutez une déclaration import à un fichier source, il est considéré comme un module externe. Une raison pour laquelle vous n'utilisez pas le fichier de définition React qui utilise un global?

https://github.com/borisyankov/DefinatelyTyped/blob/master/react/react-global.d.ts

Il me semble que cela résoudrait le problème.

J'ai également essayé react-global.d.ts , ce qui met évidemment React dans l'espace global, mais comment pourrais-je le renommer globalement et en informer Typescript?

declare var _r = React;  // error Cannot find name 'React';

Mon cas d'utilisation réel serait de pouvoir hisser un module de type utilitaire / commun dans l'espace global afin de ne pas avoir à utiliser un tas d'importations de chemins relatifs pour y accéder. Je peux le faire en Javascript, mais j'ai du mal à faire savoir au compilateur Typescript que je l'ai fait.

@ahejlsberg - Je suis sûr que vous avez bien plus de choses à faire que de supporter mes réflexions sur les cas de pointe ... :)

Vous pouvez par exemple créer un fichier de déclaration r.d.ts :

/// <reference path="react-global.d.ts"/>
declare var R: typeof React;

puis référencez simplement ce fichier partout. Ou encore mieux:

/// <reference path="react-global.d.ts"/>
import R = React;

ce qui vous permettra de référencer également les types de React en tant que R.xxx.

Je n'ai jamais vu une utilisation de typeof auparavant - plutôt cool. Cela fonctionne très bien pour les modules déjà définis à partir d'un .d.ts , mais je ne vois toujours pas de moyen de hisser un module externe défini dans Typescript dans l'espace global et de le faire savoir à Typescript. Peut-être parce que c'est un anti-pattern et que je devrais juste m'en remettre ...

Nous avons eu quelques demandes (par exemple # 2357) pour étendre typeof pour prendre en charge des modules externes, mais jusqu'à présent, il n'y a pas eu beaucoup de demande pour cette fonctionnalité.

D'une manière générale, les programmes sont soit écrits sans modules externes, soit exclusivement avec des modules externes. À part la partie bootstrap d'une application de navigateur AMD, il n'y a vraiment pas d'environnement d'exécution où le modèle mixte est même possible. Alors oui, c'est surtout un anti-pattern.

Merci d'avoir pris tout le temps de me faire plaisir à ce sujet! Je viens de commencer à explorer des modules externes (pour jouer avec les prochains frameworks Angular2 et Aurelia). Des problèmes comme # 17, # 2338 et # 2839 semblent être plus ce que je recherche à la fin. J'espère que je proposerai des commentaires plus clairs à mesure que je plongerai plus profondément dans mon projet actuel.

N'est-ce toujours pas possible de le faire? J'essaie d'utiliser TypeScript avec VueJS et j'apprécierais beaucoup si je pouvais importer quelques éléments dans l'espace de noms global afin que tous les composants puissent l'utiliser sans avoir à importer ces éléments. Y a-t-il eu des progrès ou des hacks pour faire ce travail?

@Evertt

J'ai trouvé un moyen qui fonctionne apparemment avec dactylographié 2.xx Dans mon cas, je veux exposer la bibliothèque ramda comme global R .

  1. npm install ramda @types/ramda
  2. créer un fichier typings/ramda.d.ts
  3. ajoutez le dossier typings nouvellement créé aux includes dans .tsconfig.json:
"include": [
    "typings/**/*",
     ...
]
  1. ajoutez la magie à typings/ramda.d.ts :
import * as _R from 'ramda';

export as namespace R;
export = _R; 

Maintenant, tous les fichiers ts de mon projet supposent qu'il y a un R global tapé sans que je fasse d'autres importations ou quoi que ce soit dans ces fichiers.

@geekflyer lorsque j'essaye de le faire en utilisant le code suivant dans mon types/vue.d.ts :

import * as V from 'vue'

export as namespace Vue
export = V

J'obtiens l'erreur suivante chaque fois que j'essaye d'utiliser ce global Vue quelque part:

error TS2686: 'Vue' refers to a UMD global, but the current file is a module. Consider adding an import instead.

Avez-vous eu cette erreur aussi à un moment donné? Si oui, qu'avez-vous fait à ce sujet?

Éditer

Si vous n'obtenez pas cette erreur et que vous ne savez pas pourquoi j'obtiens cette erreur, seriez-vous peut-être prêt à me montrer l'intégralité de votre tsconfig.json et peut-être même votre configuration Webpack?

Salut @Evertt en effet, je reçois aussi cette erreur maintenant. Au départ, mon code source n'utilisait pas la syntaxe du module ES6, mais une fois que j'ai refactoré certains fichiers avec cette syntaxe, j'ai eu la même erreur. J'ai fait des recherches et ce qui a fonctionné pour moi maintenant, c'est lorsque je crée un deuxième fichier globals.d.ts et que je le place également dans le dossier typings:

import * as _R from 'ramda';
import * as _mobx from 'mobx';

declare global {
  const R: typeof _R;
  const mobx: typeof _mobx;
}

En fait, ce fichier seul semble "satisfaire" le compilateur dactylographié, donc en théorie vous n'avez pas besoin des autres fichiers que j'ai mentionnés précédemment. Cependant, dans mon cas particulier (j'utilise WebStorm) lorsque je n'avais que le fichier globals.d.ts, mon IDE me demandait constamment d'importer les modules et les complétions sur ces globals étaient incomplètes. J'ai donc essentiellement gardé les deux fichiers dans le répertoire typings qui satisfait le typage et mon IDE. Pas vraiment sympa, mais pour les quelques globaux que l'on utilise généralement, je suppose que c'est correct de maintenir ces fichiers.

Voici mon tsconfig.json pour référence:

{
  "compilerOptions": {
    "target": "ES5",
    "module": "amd",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "lib": [
      "ES6",
      "DOM",
      "ScriptHost"
    ],
    "sourceMap": true,
    "strictNullChecks": true
  },
  "include": [
    "types/**/*",
    "src/**/*"
  ]
}

Je n'utilise pas Webpack ou quoi que ce soit à regrouper. Je transpile simplement les fichiers individuels et les charge via le système de modules https://github.com/SAP/openui5 (qui est similaire à AMD) et les associe pour la production uniquement.

La version Typecript est: 2.2.1

J'espère que ça t'as aidé.

@geekflyer merci qui a été très utile

Cette page vous a été utile?
0 / 5 - 0 notes