Typescript: Prise en charge de la recherche de modules sous node_modules lors de l'importation

Créé le 25 juil. 2014  ·  138Commentaires  ·  Source: microsoft/TypeScript

Mise à jour 5 novembre 2015

La fonctionnalité demandée ci-dessous est actuellement implémentée en tapuscrit depuis au moins la 1.8 avec une différence principale :

Au lieu d'avoir les propriétés typescript.main et typescript.definition , il n'y a qu'une seule propriété typings que vous pouvez pointer vers un fichier d.ts ou un .ts normal

Si vous développez un module à utiliser uniquement localement, vous pouvez faire pointer le typings vers un fichier .ts , mais si vous envisagez de publier le module, il est recommandé de le faire pointer vers un fichier d.ts . C'est parce que vous ne voulez pas que vos consommateurs de module recompilent vos fichiers de module, consommez simplement ses typages.

J'ai configuré un exemple d'utilisation ici:
https://github.com/chanon/typescript_module_example

Il y a une page de documentation ici qui contient plus d'informations:
http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html

Merci aux développeurs TypeScript et à tous les contributeurs.

Le problème d'origine / la demande de fonctionnalité suit


Motivation

Dans TypeScript, il est beaucoup plus difficile de réutiliser les modules TypeScript que de réutiliser les modules npm en JavaScript.

Il serait avantageux que le compilateur TypeScript soit suffisamment intelligent pour rechercher dans les dossiers node_modules et les fichiers package.json.

La raison en est que les développeurs de modules npm qui utilisent TypeScript pourraient commencer à écrire et à distribuer des modules via npm lui-même. TypeScript serait en mesure de s'appuyer sur l'infrastructure et le large support de npm.

Exemple pour node_modules

Si nous avions:

./node_modules/concator/index.ts
./myApp.ts

Et dans index.ts nous avions :

export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}

dans myApp.ts :

import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params

Donc, fondamentalement, le compilateur est assez intelligent pour trouver le module dans node_modules et il utilise automatiquement la version dactylographiée (index.ts).

Ensuite, lorsque le code est compilé en JavaScript, il utilise naturellement la version JavaScript.

Importation de dossiers en tant que modules

Un cas plus basique prend en charge la règle populaire de Node.js de http://nodejs.org/api/modules.html#modules_folders_as_modules comme suggéré par @vvakame ci-dessous et dans le numéro 207 fermé (semi-dupliqué).

typescript.main dans package.json

Il pourrait y avoir un ajout aux fichiers package.json pour spécifier où se trouve le fichier .ts principal d'un module TypeScript npm. Ce serait similaire à la clé main qui spécifie où se trouve le fichier JavaScript / .js principal, mais pour TypeScript à la place.

Par exemple package.json pour un module npm nommé "myModule" situé à node_modules/myModule/package.json

{
     "main": "./dist/index.js",
     "typescript": {
          "main": "./src/index.ts"
     }
}

Dans cet exemple, node_modules/myModule/src/index.ts serait le fichier TypeScript principal et faire un import myModule = require("myModule"); importerait le fichier node_modules/myModule/src/index.ts .

Pour un codeur JavaScript écrivant var myModule = require("myModule"); dans un fichier JavaScript, l'exigence chargerait le fichier node_modules/myModule/dist/index.js comme d'habitude.

Comme on peut le voir dans cet exemple, le TypeScript src se trouve dans le dossier node_modules/module-name/src et les fichiers JS compilés seraient dans node_modules/module-name/dist .

Quelque chose comme cela pourrait être un (semi) standard pour les modules TypeScript npm afin que la source TypeScript soit proprement séparée de la sortie JavaScript compilée.

Un cas plus basique, comme suggéré par @vvakame ci-dessous, prend en charge la règle Node.js populaire de http://nodejs.org/api/modules.html#modules_folders_as_module

typescript.definition dans package.json

Une autre clé possible pour package.json pour les modules npm non TypeScript (JavaScript simple) pourrait être typescript.definition . Cela pointerait vers un fichier .d.ts qui définit le module pour les utilisateurs TypeScript du module npm.

Alors qu'un
import $ = require('jquery');
lirait automatiquement un fichier jquery.d.ts défini dans la clé typescript.definition dans le package.json de jQuery et ferait $ le type correct.

Exemple de format :

{
     "main": "./dist/index.js",
     "typescript": {
          "definition": "./index.d.ts"
     }
}

(Ce format est déjà utilisé par tsd comme @Bartvds l' explique ci-dessous.)

Ensuite, nous, les codeurs TypeScript, n'aurions qu'à essayer d'obtenir autant de mainteneurs de modules npm non-TypeScript pour fusionner nos demandes d'extraction contenant nos fichiers .d.ts et les clés package.json typescript.definition .

Si nous réussissons avec cela, alors la vie des codeurs TypeScript serait un bonheur ... plus de gestion séparée des fichiers DefinitelyTyped .d.ts. Installez simplement npm et vous obtenez également vos définitions TypeScript! Automatiquement et à jour avec la version du module installé.

Liste des avantages

Ce que nous obtenons de tout cela est

  • Les modules npm peuvent être écrits en TypeScript.
  • Les codeurs TypeScript et JavaScript peuvent utiliser ces modules
  • Les utilisateurs du module qui utilisent TypeScript bénéficient des avantages du typage statique sans que le codeur (ou l'utilisateur) du module n'ait à utiliser la méthode habituelle d'écriture (ou de génération) de fichiers .d.ts séparés (ainsi, lorsque le code source du module est déjà dans TypeScript nous n'avons pas besoin d'avoir un autre fichier .d.ts à maintenir)
  • Il y aurait un moyen de réutiliser et de distribuer facilement les modules TypeScript à l'aide de npm que tout le monde connaît déjà
  • Cela pourrait aider à promouvoir l'utilisation de TypeScript lui-même, car les codeurs JavaScript qui utilisent les modules npm écrits en TypeScript pourraient voir à quel point la source TypeScript est agréable/meilleure et essayer de passer à celle-ci. Ou ils pourraient vouloir contribuer au module et puisque la source est en TypeScript, ils devraient l'apprendre, ce qui pourrait les amener à l'aimer et à décider de l'utiliser dans leurs propres projets.
  • Fondamentalement, cela aiderait à développer la communauté TypeScript grâce à tout le partage de code qui pourrait en résulter. À l'heure actuelle, le code TypeScript de chacun est principalement le sien / dans son propre silo. C'est en fait probablement une chose extrêmement importante car ne pas avoir un moyen approprié/facile de partager/distribuer/réutiliser les modules limite probablement la croissance du langage. [1]
  • La réutilisation de modules dans des projets internes serait beaucoup moins compliquée et réduirait le besoin de tous ces chemins relatifs vers les fichiers .d.ts et les chemins relatifs dans les modules requis, et les éléments généraux .d.ts. (En ce moment, lorsque j'écris du code TypeScript, je trouve que je dois apprendre à compter ../../ s)
  • Cette approche prend également en charge Browserify/Webpack car Browserify/Webpack regarde également sous node_modules, ce qui permet des modules TypeScript distribués facilement réutilisables/npm pour le serveur et le navigateur.
  • Les modules npm non-TypeScript peuvent facilement être utilisés dans TypeScript avec des informations de type grâce à l'ajout de la clé typescript.definition . Cela permet de regrouper les fichiers de définition .d.ts avec le module npm afin que la mise à jour d'un module npm mette automatiquement à jour son fichier de définition .d.ts. Cela supprime la nécessité de mettre à jour manuellement les fichiers .d.ts.
  • L'utilisation de fichiers de définition via typescript.definition est plus simple car il s'agit simplement d'une instruction import moduleName = require("moduleName") sans avoir besoin d'un ///<reference ... séparé
  • L'utilisation de fichiers de définition via le typescript.definition devrait également permettre l'utilisation de différentes versions du module dans la même base de code sans que les noms de type ne se heurtent.

Proposition détaillée

@ Nemo157 a écrit une proposition très détaillée sur la façon dont tout cela devrait fonctionner à :

TypeScript proposé nécessite une sémantique de résolution
https://gist.github.com/Nemo157/f20064a282ee620f3877

Un ajout dans la proposition est l'utilisation de dossiers /typings qui peuvent contenir des fichiers de définition qui peuvent être automatiquement gérés par des outils tels que tsd pour les modules JavaScript npm qui n'incluront pas de fichiers de définition dans leurs référentiels .

Derniers faits à l'appui

Étant donné que TypeScript se compile en JavaScript qui s'exécute principalement à deux endroits : node.js et dans les navigateurs, la prise en charge de node_modules est bénéfique aux deux endroits (pratiquement tous les endroits où TypeScript est utilisé) en raison de npm et de Browserify/Webpack.

c'est à dire. il n'y a aucune raison de proposer un schéma différent lorsque node_modules est ce que tous les utilisateurs de TypeScript utilisent déjà pour peut-être 75% à 100% de tout leur code JavaScript. (Suppression de 25% pour peut-être les utilisateurs de RequireJS.)

Notes de bas de page

[1] - BTW, je vois qu'il existe un gestionnaire de packages NuGet (?) de Microsoft qui peut distribuer des modules dactylographiés (?), mais venant d'un arrière-plan axé sur node.js (non axé sur .NET), je ne vois pas NuGet devenir largement utilisé en dehors des magasins axés sur Microsoft, d'autant plus que npm est _the_ standard pour node.js et est également un standard de premier plan pour JavaScript côté client. Si je n'utilisais pas TypeScript, je n'aurais jamais entendu parler de NuGet. Le codeur JavaScript node.js / côté client moyen préférerait probablement utiliser npm, le même outil qu'il utilise déjà plutôt que d'avoir à utiliser quelque chose de spécifique à Microsoft tel que NuGet. (Je ne sais rien de NuGet, donc ce que je dis ici n'a peut-être pas d'importance.)

Committed Suggestion

Commentaire le plus utile

Dans tous les cas, le compilateur prétend actuellement qu'il ne peut pas trouver le module, alors qu'en réalité, il refuse simplement d'importer le module sans définition de type. Ce n'est pas vraiment utile, n'est-ce pas ?

Tous les 138 commentaires

[déplacé vers typescript.main dans package.json dans la description du problème ci-dessus]

:+1:
Je pense que http://nodejs.org/api/modules.html#modules_folders_as_modules est la règle très populaire de Node.js.

autre exemple.

./test/index.ts

export function hello() { return "Hello, world"; }

./main.ts

import test = require("./test/");
console.log(test.hello()); // print "Hello, world"

[déplacé vers typescript.definition dans package.json dans la description du problème ci-dessus]

Une solution serait de le résoudre avec un meilleur outillage. Par exemple, import foo = require('foo') vous donne un indice pour rechercher un node_module + package.json local (foo est un projet ts) ou une définition DT (foo est un projet js où les auteurs de bibliothèques ne veulent pas maintenir le ts def) .

POUR VOTRE INFORMATION; Je teste en fait quelque chose de similaire à ceci dans TSD; un moyen d'exposer et de lier les définitions qui sont regroupées dans les packages npm (ou bower).

C'est dans ma version de développement pour 0.6, et cela fonctionne en ajoutant un élément typescript au package.json (ou bower.json), avec un sous-élément definition (un sous-élément parce que peut-être un jour il y aurait source aussi, ou peu importe).

{
    ...
    "main": "./index.js",
    "typescript": {
        "definition": "./foo.d.ts"
    }
    ...
},

Ensuite, vous pouvez exécuter une commande sur TSD, actuellement tsd link et elle analysera tous les fichiers package.json dans node_modules (ou bower ou autre), trouvera cette propriété si elle est définie et y ajoutera une référence au central tsd.d.ts Offre groupée

Exemple : défini ici et utilisé ici

@Bartvds C'est plutôt sympa. Cela pourrait être la première étape pour avoir .d.ts dans les packages npm. J'aime la structure package.json avec "definition" dans "typescript", c'est beaucoup plus organisé.

Si le compilateur TypeScript lui-même pouvait le lire automatiquement, ce serait très cool.

Marquer ceci pour discussion - une résolution de module externe plus intelligente est quelque chose dont nous devons parler pour comprendre les différents scénarios ici. Cela a été évoqué précédemment et nous avons apporté quelques modifications à la version 1.0.

Discutez également de #207 - en regardant sous 'index'

:+1:

@chanon tsMain n'est pas nécessaire si nous utilisons la génération de déclarations.

Oui, le problème est extrêmement important même pour les navigateurs - de nombreux projets utilisent browserify/packify et donc des dispositions de répertoires compatibles avec les nœuds

:+1:

Il y a déjà eu du travail dans ce domaine dans le référentiel codeplex, une pull request par leebyron et une par kayahr .

J'avais l'intention d'essayer de porter l'un d'entre eux sur le nouveau référentiel, mais il semble que le code associé ait été beaucoup réorganisé.

J'ai écrit une proposition sur la façon d'ajouter ceci au compilateur TypeScript . Cela inclut également la recherche dans le répertoire typings car cela sera important lorsque vous travaillerez avec des modules javascript qui ne conserveront pas leurs propres définitions de dactylographie. Malheureusement, faire en sorte que tout cela fonctionne de manière transparente avec tsd demandera encore un peu de travail car l'exigence que les fichiers /// <reference d soient des déclarations externes ambiantes rend les choses un peu poilues. Je vais jeter un œil à l'implémentation de ceci sur une branche et fournir quelques exemples de modules l'utilisant.

Semble raisonnable. Cela couvrira-t-il les modules avec des dépendances de type conflictuelles ? Je veux dire si une application importe A et B, et que B dépend également de A. Il est facile de tomber dans des erreurs de type en double s'il existe deux copies des déclarations externes.

Cela ne devrait pas être le cas, ils devraient être résolus en différents noms de modules externes, donc déclarez des types indépendants nommés de manière identique dans différents modules. La vérification de type structurel devrait alors permettre aux différents modules d'interagir sans problème.

C'est l'un des problèmes majeurs avec les définitions tsd actuelles que cela tente de résoudre, en définissant des modules ambiants externes, il n'y a aucun moyen pour eux de gérer plusieurs versions d'une bibliothèque avec des noms identiques, mais des types légèrement différents .

@joewood aussi il y aura des problèmes entre les différentes versions de A

├── [email protected]
└── [email protected]
    └── [email protected]

il n'y a aucun moyen pour eux de gérer plusieurs versions d'une bibliothèque avec des noms identiques, mais des types légèrement différents.

intéressé d'entendre des solutions à la même chose. TypeScript a une portée de variable de niveau global pour les déclarations ambiantes

Même si les versions correspondent, pour le moment, je vois des problèmes avec deux fichiers de déclaration ambiants différents, mais correspondants, provoquant des erreurs de symboles en double. La directive /// reference définie localement doit être résolue d'une manière ou d'une autre en un seul fichier. Soit cela, soit l'identité de type doit inclure le chemin et le typage structurel s'occupera des incompatibilités de version, etc.

@joewood Yep, j'espère que ce sera corrigé dans la majorité des cas en changeant require pour charger les définitions correctes, en évitant /// reference dans la mesure du possible. Les modules externes seront identifiés par leurs chemins absolus au lieu d'avoir des déclarations ambiantes, de sorte que le chargement de plusieurs modules du même nom à partir de chemins différents et de versions différentes devrait être possible.

Oui, c'est ce que j'espère être corrigé dans la majorité des cas en changeant require pour charger les définitions correctes, en évitant /// la référence dans la mesure du possible.

:+1:

:+1: Merci @Nemo157 et tout le monde pour la discussion.

J'ai mis à jour le texte du problème principal pour fusionner les ajouts de package.json et lié à la proposition de @ Nemo157 .

:+1:

J'ai fait une mise en œuvre initiale de ma proposition ainsi que la création d'un ensemble d'exemples de modules pour montrer que toutes les différentes façons de créer un module fonctionneront. Y compris l'utilisation de différentes versions de la même bibliothèque dans différents sous-modules.

:+1:

Dossiers sous forme de modules avec index.ts :+1 :

:+1:

:+1:

:+1:

:+1:

:+1: :+1: :+1:

:+1: :+1: :+1: :+1:

Commentant pour renvoyer cela sur notre radar.

J'ai eu beaucoup de succès avec la suggestion de @Bartvds :

Ensuite, vous pouvez exécuter une commande sur TSD, actuellement le lien tsd et il analysera tous les fichiers package.json dans node_modules (ou bower ou autre), trouvera cette propriété si elle est définie et y ajoutera une référence au bundle central tsd.d.ts dans votre projet.

Donc, envisagez de soutenir typescript en package.json car c'est ainsi que la communauté a évolué.

Nous avons certainement besoin de tsc pour connaître le dossier node_modules si TypeScript va être largement utilisé dans la communauté node.js. J'utilise actuellement des liens symboliques vers des modules qui font partie de mon projet de développement (en utilisant npm-workspace), et j'ai deux options pour le moment :

  • importez directement depuis node_modules, ce qui semble faux : import Foo = require("node_modules/mymodule/Foo");
  • obtenez tsc pour générer les fichiers de déclaration, puis assemblez-les à l'aide d'un fichier de déclaration de module géré manuellement qui bascule les noms de module de chaîne

tsc pourrait-il vérifier le nom du module externe dans les déclarations d'importation, puis lors de la résolution du chemin, appliquer également node_modules de la même manière que le runtime node.js ? Une option du compilateur peut également activer ou désactiver cette option.

:+1: :+1: :+1:

tsc pourrait-il vérifier le nom du module externe dans les déclarations d'importation, puis lors de la résolution du chemin, appliquer également node_modules de la même manière que le runtime node.js

Ça devrait être comme cela. La manière actuelle de simplement rechercher l'arborescence des répertoires pour trouver un fichier portant ledit nom n'a aucune ressemblance avec les contextes d'exécution JS.

C'est sur ma liste depuis un moment déjà. essaiera de l'obtenir dans la prochaine version.

Nous ( Booktrack ) utilisons TypeScript pour tous nos développements Web, et nous sommes confrontés à des défis similaires aux développeurs de node.js. Je prends la parole parce que la voix des développeurs Web ne semble pas aussi forte que celle des développeurs de nœuds.

Solutions (dans l'ordre du pire pour nous au meilleur pour nous) :

  1. résolution des noms de modules externes de niveau supérieur via une recherche codée en dur dans node_modules
  2. aucun contrôle sur la résolution des noms de modules externes de niveau supérieur
  3. un indicateur de compilateur pour contrôler la résolution facultative des noms de modules externes de niveau supérieur dans le répertoire node_modules
  4. un paramètre de compilateur "chemin(s) de recherche de module(s)" pour contrôler la résolution facultative des noms de modules externes de niveau supérieur dans le(s) chemin(s) donné(s)
  5. un paramètre "résolveur de modules" du compilateur pour fournir au compilateur un plugin JS qui résoudra tous les noms de modules externes (pas seulement de niveau supérieur)
  6. crochets appropriés dans les services de langage de telle sorte que la résolution du nom du module externe soit contrôlable

L'option 1 est terrible, je préfère l'option 2.

Les options 5 et 6 autoriseraient des utilisations exotiques des instructions d'importation, telles que celles trouvées lors de l'utilisation de plugins requirejs ou webpack. L'idée de base : le compilateur délègue toutes les recherches de noms de modules externes (pas seulement au niveau supérieur) à un tiers (un plugin ou un rappel). Le délégué, étant donné le chemin vers le module en cours de compilation et le nom du module externe, renvoie au compilateur le chemin du système de fichiers OU les informations de type pour le nom de module donné.

Je serais heureux si l'option 4 était mise en œuvre, ravi si l'option 6 était mise en œuvre et ravi si l'option 4 et l'option 6 étaient mises en œuvre.

Que diriez-vous d'un --basePath pour la racine de recherche de votre module, toutes les importations de modules seront examinées par rapport à ce chemin. Cela ne s'applique qu'à AMD.

Je pense que le problème de nœud est beaucoup plus simple, nous avons juste besoin de l'implémenter :)

Notez que nous avons en fait obtenu une implémentation (et des tests) de @ Nemo157 ici il y a longtemps https://github.com/Microsoft/TypeScript/issues/247#issuecomment -57422329

D'accord avec @mark-buer et @mhegazy , l'option 4 un chemin de recherche devrait être une solution simple. Une solution plus élaborée dans le service linguistique (option 6) est certainement nécessaire à plus long terme.

_Vaut la peine d'être ajouté_ : cela ne résoudra pas à lui seul le problème de réutilisation de TypeScript dans npm en raison du problème de symbole en double pour les références de type courantes #1125. Il faut vraiment éviter ///en utilisant les fichiers .tsconfig et corrigez cela correctement en regroupant les packages dans un seul module typé externe, comme suggéré au n ° 17

Un autre vote pour faire reconnaître le dossier node_modules par le compilateur dactylographié.

Pour les modules CommonJS, le typescript devrait idéalement suivre la même résolution de nom de fichier que require.resolve (comme indiqué par le pseudocode sur cette page : http://nodejs.org/api/modules.html#modules_all_together.

cette fonctionnalité est essentielle pour permettre l'intégration du compilateur Typescript dans d'autres packages de nœuds, tels que browserify. Le correctif de @ Nemo157 fait du bon travail, mais il ne permet pas de tester facilement avec les empaqueteurs existants car la plupart sont passés à des versions ultérieures de dactylographie et ne sont plus compatibles avec son code

Où le répertoire node_modules doit-il être par rapport aux sources ?

Atom-TypeScript prend désormais en charge typescript.definition prêt à l'emploi. Détails : https://github.com/Microsoft/TypeScript/issues/2829

Vous pouvez également créer facilement de tels packages en utilisant atom-typescript :rose: voir à nouveau #2829

Limitation

Cela fonctionnera _parfaitement_ si vous partagez un paquet qui ne dépend d'aucune bibliothèque externe. Si c'est le cas, nous avons besoin d'un algorithme de résolution de conflit de module.

Je suis ouvert aux suggestions pour ce cas, mais mon plan est :

  • nous faisons des choses intelligentes en lisant un tel d.ts sans donner à TypeScript les commentaires externes reference (par exemple node.d.ts ici https://github.com/TypeStrong/atom-typescript-examples /blob/master/node/node_modules/example-typescript-b/definition/sample-bdts) Et à la place pointant vers notre propre .d.ts si nous l'avons dans nos Typings.

Est-ce que cela va rester sur la bonne voie pour 2.0 ? Cela semble être une fonctionnalité importante pour l'adoption de Node.js, ce qui est actuellement douloureux, même avec DefinitelyTyped et autres.

Cela semble être une fonctionnalité importante pour l'adoption de Node.js, ce qui est actuellement douloureux, même avec DefinitelyTyped et autres.

@LPGhatguy Veuillez consulter https://github.com/Microsoft/TypeScript/issues/2338. @vladima y travaille mais ne pense pas qu'il ait encore été assigné à un jalon :rose:

@LPGhatguy, nous essayons de l'obtenir dans la prochaine version. bientôt je l'espère.

@mhegazy Tu veux dire 1.6 ? Ce serait génial!

Est-ce lié au #2338 ?

oui pour TypeScript 1.6 (du moins c'est ce que nous essayons de faire), un oui pour #2338 ; il y a quelques autres changements et problèmes à ce sujet, notamment # 3147 et # 4154

Alors, pourquoi est-il marqué comme TypeScript 2.0 comme jalon ?

merci @heycalmdown , a supprimé le jalon. nous ne marquons généralement pas les jalons des suggestions. j'espère que nous aurons une mise à jour d'ici une semaine environ sur ce problème. restez à l'écoute.

Je voudrais sonner en demandant que le support du module ES6 suive également cela (ce que je suppose que ce serait?)

Dactylographies pour

import mylib = require('mylib');
mylib.foo(mylib.bar);

devrait se comporter de la même manière que

import { foo, bar } from 'mylib';
foo(bar);

Je voudrais sonner en demandant que le support du module ES6 suive également cela (ce que je suppose que ce serait le cas?

@DavidSouther Ce serait _automatiquement_ le cas. La recherche entre les deux est cohérente :rose:

ceci est géré par #4154.

Si j'utilise la nuit, à partir de demain, je devrais m'attendre à ce que l'importation de modules de nœud "fonctionne simplement" ?

Question:
Je pense que c'est une convention courante d'avoir des fichiers nommés
"index" dans commonJS et
"principal" dans AMD
pour les trajets courts.
Dans la question du haut, l'auteur importe
/node_modules/concator/index.ts comme
import concator = require('concator');

S'il vous plaît, pardonnez-moi - je suis en train de déterminer si la résolution d'index est également prise en charge maintenant et qu'en est-il de index.ts ou main.ts dans AMD nécessite une résolution?
J'envoie également un ping à @basarat pour savoir s'il est/sera pris en charge par https://github.com/TypeStrong/atom-typescript car maintenant cela ne me permet pas d'exiger un index.ts comme mentionné ci-dessus.

@sebilasse , si vous utilisez typescript@next aujourd'hui, cela devrait fonctionner avec --module commonjs

import concator = require('concator'); // resolves to node_modules/concator/index.ts

Il n'y a pas de changement dans la résolution AMD des versions précédentes.

@DavidSouther ça devrait être dans typescript@next aujourd'hui. essayez-le et faites-nous savoir comment ça se passe.

@mhegazy @basarat :+1: d'accord. Mais que pensez-vous de la résolution AMD pour main.ts ou index.ts - ne devrait-elle pas être cohérente à l'avenir ?

@sebilasse , pour AMD je pense que nous devons faire quelque chose comme noté par @vladima dans #2338 (section pour : RequireJS/ES6 module loader).

Très agréable!! \o/

@mhegazy Ne fonctionne toujours pas comme je m'y attendais.

J'ai rassemblé https://github.com/DavidSouther/typescript-example-using-node avec mon cas d'utilisation "idéal". tslib est une bibliothèque simple qui exporte une seule fonction. tsclient dépend de tslib, ainsi que readline des packages Node. Le script de configuration est pratique à installer, lier et exécuter. J'ai inclus une course et annoté les parties inattendues avec des commentaires en ligne.

% ./setup
...
> [email protected] build ~/ts-node/tslib
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
...
> [email protected] build /Users/southerd/devel/tmp/ts-node/tsclient
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
# Expect this to find tslib, but fail type checking.
# See tsclient/app.ts for details
src/app.ts(4,21): error TS2307: Cannot find module 'tslib'.

+ node ./dist/app.js # This works as expected!
What would you ask? What is the meaning of life?
42
+ set +x

Je ne reçois pas non plus de support linguistique pour les importations de tslib dans tsclient (VSCode Version 0.7.0 (0.7.0)), bien que je ne sois pas tout à fait sûr du TSC qu'il utilise ou de la manière de le modifier.

Le compilateur @DavidSouther TypeScript vérifie le champ 'typings' dans package.json pour trouver les fichiers '.d.ts'. Avec ce changement , j'obtiens src/app.ts(13,7): error TS2322: Type 'string' is not assignable to type 'number'. qui ressemble à une erreur légitime

Ah, j'ai dû rater cette doc. J'ai toujours le deuxième problème - comment changer la version de VSCode tsc ?

vous pouvez fournir un emplacement SDK TypeScript personnalisé à VSCode via le paramètre "typescript.tsdk" - il doit pointer vers le dossier contenant tsserver.js et les fichiers '.d.ts' standard. Dans le cas où TypeScript est installé en tant que package npm, ce sera quelque chose comme

// Place your settings in this file to overwrite the default settings
{   
    "typescript.tsdk": "C:\\Sources\\bugs\\node\\typescript-example-using-node\\tslib\\node_modules\\typescript\\lib"       
}

Quelqu'un at-il obtenu un échantillon de travail? J'ai essayé tout l'après-midi de jouer avec ça, mais je finis toujours par

error TS2307: Cannot find module

Pour le moment, le code se trouve dans node_modules/my-module/. Et j'ai défini un index.ts qui s'occupe de tout exporter, et je l'ai référencé dans le package.json sous typescript.main. Dans le projet consommateur, j'ai essayé d'importer {AClass} à partir de 'my-module' ; et importez mon-module = require('mon-module'); Ils conduisent tous les deux à la même erreur avec le tapuscrit 1.7.0-dev.20150901.

Lors de la résolution d'un module avec un nom non relatif, avec --module commonjs , le compilateur recherchera un .d.ts qui correspond au nom dans node_modules\name\index.d.ts ou cherchera dans package.json pour une propriété typings , et chargez le .d.ts vers lequel elle pointe.

d'après votre description, on dirait que vous le définissez sur index.ts , vous ne voulez pas vraiment compiler vos dépendances, vous voulez simplement consommer leurs typages, vous devez donc le définir sur index.d.ts la place.

J'ai mis à jour les étapes de l'algorithme de résolution du module de nœud pour refléter l'implémentation : https://github.com/Microsoft/TypeScript/issues/2338

@DavidSouther J'ai apparemment exactement le même problème. Lorsque je compile avec une dépendance dans node_modules, il ne peut pas résoudre le module et génère une erreur, mais il génère toujours le js, et si je l'exécute, il s'exécute. Peut-être est-ce dû à ma configuration, je ne sais pas. Mon d.ts est majoritairement vide, j'ai un index.ts qui s'occupe d'importer et de réexporter toutes les classes de mes modules définis dans de nombreux fichiers .ts. Et puis mon fichier d.ts fait simplement référence à cet index.ts et exporte tout depuis index.ts comme ceci :

/// <reference path="index.ts" />

declare module 'my_module' {
    export * from 'index';
}

De plus, il compile toujours le ts à partir de node_modules, donc je devrais ajouter une tâche propre pour le supprimer après la compilation. Existe-t-il une description de la fonctionnalité quelque part qui résume le processus ?

edit : je l'ai fait fonctionner, mais c'est super hacky et génère toujours des erreurs. J'ai créé un d.ts avec dts-generator, puis j'ai importé mes classes comme ceci :

import MyClass from '../../node_modules/my_module/dist/MyClass';

Si j'utilise import MyClass depuis 'my_module/MyClass', je l'obtiens pour compiler sans erreur, mais lors de l'exécution, j'obtiens l'erreur ne peut pas trouver le module 'my_module/MyClass'. Avec la solution ci-dessus, il pointe directement vers le .js compilé et au moment de l'exécution, cela fonctionne d'une manière ou d'une autre, même s'il affiche l'erreur Impossible de trouver le module au moment de la compilation.

Vous avez toujours des problèmes d'importation à partir de sous-modules (par exemple, npm install angular2, import { Inject, Binding } from 'angular2/di' . Nous travaillerons à obtenir un cas de test contenu ce soir.

Ne pensez pas que angular regroupe déjà ses typages de la manière attendue par le compilateur TypeScript.

C'est probablement vrai; Je vais travailler avec eux et voir où ça se termine.

cette fonctionnalité fonctionne bien sur TypeScript 1.1, par exemple https://github.com/Nemo157/typescript_w_node_modules_example

mais échec dans tapuscrit 1.5.3, quelque chose a changé?

------ mettre à jour ---------

Je sais qu'il sortira en 1.6, merci

Je ne peux obtenir ce "demi-fonctionnement" qu'en 1.6.2

Tout d'abord, j'emballe une bibliothèque avec un my-lib.d.ts dans le répertoire dist et pointe vers ce fichier dans l'attribut package.json du fichier typings (par exemple "typings" : "dist/my-lib.d.ts" )

Ensuite, j'importe cette bibliothèque dans un fichier TypeScript Test.ts en utilisant

import { MyObject } from "my-lib"

MyObject est correctement importé et le code js est émis lors de la transpilation.
Visual Studio Code fournit même l'achèvement sur MyObject

Cependant, je reçois des avertissements du compilateur qui :
Test.ts(10,60): error TS2306: File '[]/node_modules/my-lib/dist/my-lib.d.ts' is not a module.

Visual Studio Code affichera en fait l'importation comme une erreur matérielle

Tous les modules importés à partir d'un package de nœud doivent être des "modules externes" et non des "déclarations de module ambiant". c'est-à-dire pas de déclarations declare module "foo" {.. } , mais plutôt des déclarations d'importation ou d'exportation de niveau supérieur dans le fichier.

Donc, si votre paquet "my-lib" est écrit en tapuscrit, construisez-le simplement avec --declarations et définissez les typages sur le fichier .d.ts de votre module principal. si ce n'est pas le cas, et que vos saisies sont quelque chose que vous avez écrit à la main ou que vous avez définitivement tapé, vous devrez soit le remplacer par un module externe, soit attendre que # 4665 soit résolu (espérons-le bientôt).

La raison de cette restriction est que cela peut entraîner une pollution globale de la portée et des conflits ultérieurement pour les utilisateurs de votre package. il y a une longue discussion à ce sujet dans #4665.

Voici de la documentation pour de futures recherches : https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

@mhegazy Merci pour votre réponse rapide qui m'a vraiment aidé dans ma quête pour automatiser la construction de librairies commonjs, écrites en Typescript, qui peuvent être consommées à la fois par du code Javascript et TypeScript.
La syntaxe et la résolution import/export ont évolué si rapidement récemment que ce qui, je suppose, manque actuellement est un guide définitif sur la façon d'en créer un.

Je l'ai fait fonctionner ... avec une mise en garde (et donc une autre question)

Voici une vue simplifiée de l'installation.

La bibliothèque se compose de trois objets A1, A2 et B dans 2 fichiers dactylographiés A.ts et B.ts ; quelque chose comme

sources

A.ts

class A1{}
class A2{}
export { A1, A2 }

B.ts

class B{}
export { B }

Ce que nous voulons exposer est collecté dans un index.ts :

export * from './A'
export * from './B'

construire
La construction est effectuée à l'aide de grunt et les drapeaux --module commonjs et --declaration sont définis sur tsc 1.6.2
Le résultat final de la construction est un arbre qui ressemble à

    package.json
    dist/
        js/
             A.js
             B.js
             index.js
        typings/
             A.d.ts
             B.d.ts
             index.d.ts

package.json contient ces deux entrées :

"main": "dist/js/index.js",
"typings": "dist/typings/index.d.ts"

L'utilisation de cette bibliothèque dans TypeScript 1.6.2 avec un simple import {A1, A2, B} from "mylib" fonctionne parfaitement. Les dépendances à plusieurs niveaux (c'est-à-dire les librairies qui s'importent mutuellement) fonctionnent bien aussi.

Là où des problèmes surviennent, c'est lorsque la bibliothèque dépend d'une autre bibliothèque qui n'est _pas_ une bibliothèque TypeScript.
Disons que la bibliothèque dépend de Node.js.
Dans l'un des fichiers source, il y aura une référence aux typages de NodeJS, par exemple
///<reference path="../typings/node/node.d.ts"/>

Lors de la transpilation, cette instruction <reference > va se retrouver dans le fichier de déclaration correspondant ; le problème est que le chemin vers node.d.ts est probablement erroné ou inexistant.
Y a-t-il une manière recommandée d'aller à ce sujet ?

_Note_ : ce problème est atténué par l'utilisation sur un fichier index.ts pour exposer les parties intéressantes de la bibliothèque, puisque index.ts n'a aucune raison de contenir une instruction <reference > et avec 1.6 .2, le compilateur ne semble pas se soucier du fait qu'Adts a un chemin invalide dans l'instruction de référence

@bgrieder Nous gérons cela dans Phosphor en utilisant tsconfig.json :
https://github.com/phosphorjs/phosphor-widget/blob/master/src/tsconfig.json

Nous ajoutons simplement les typages externes dont nous avons besoin aux fichiers compilés. Cela signifie que si l'un de ces types externes fait partie de notre interface publique, les consommateurs du code devront également fournir ces typages externes dans le cadre de leur construction. _C'est d'accord_. Si nous devions regrouper ces définitions et que d'autres bibliothèques utilisées par le consommateur _également_ regroupaient ces mêmes définitions, il y aurait des conflits de symboles en double.

@sccolbert Oui !
Je craignais que la suppression des instructions <reference ...> n'interrompe l'auto-complétion sur tous les IDE, mais bon, non : au moins Visual Studio Code 0.8.0 semble être assez intelligent pour sélectionner ces définitions dans le tsconfig.json fichier ! (après un redémarrage)

Terminé avec reference . Excellent !

@sccolbert

Que se passe-t-il si vous utilisez un projet simple Node.js dans celui-ci et *.d.ts pour celui-ci, comment la solution tsconfig vous aide-t-elle ?

@heycalmdown vous ajoutez simplement le d.ts au champ files sur le tsconfig , voici un exemple qui fait cela :

https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/tsconfig.json#L11
https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/index.ts#L10

Notez que nous devons utiliser require ici au lieu de import uniquement à cause de la façon dont le fichier d.ts pour expect.js est écrit en interne.

C'est bon je l'ai. Vos référentiels ressemblent à une sorte de bon exemple.

Cela a-t-il réellement été implémenté dans TypeScript 1.6.2 ?

Si c'est le cas, quelqu'un peut-il me dire ce que je fais mal ici ? :
https://github.com/chanon/typescript_module_example

Vous voulez probablement la syntaxe d'importation es6.

Le mercredi 4 novembre 2015 à 6 h 10, chanon [email protected] a écrit :

Cela a-t-il réellement été implémenté dans TypeScript 1.6.2 ?

Si c'est le cas, quelqu'un peut-il me dire ce que je fais mal ici ? :
https://github.com/chanon/typescript_module_example


Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/Microsoft/TypeScript/issues/247#issuecomment -153688004
.

Je viens de le mettre à jour pour utiliser la syntaxe d'importation es6 et j'obtiens toujours les mêmes erreurs (impossible de trouver le module).

@chanon les packages package.json pour node_modules doivent avoir une clé typings qui pointe vers un fichier d.ts , _pas_ une clé typescript pointant .ts fichiers comme vous en avez maintenant.

Nous utilisons exclusivement la résolution des modules de nœuds dans PhosphorJS (sur TS 1.6.2) et cela fonctionne bien. Voici un exemple : https://github.com/phosphorjs/phosphor-widget/blob/f908341cb1d46ada8ad8149e695a75e7ea2fde57/package.json#L6

Merci @sccolbert , cependant ma proposition initiale (en haut de ce numéro) était d'autoriser une propriété typescript.main dans package.json qui pointerait vers le point d'entrée principal de TypeScript pour les packages de modules de nœud écrits en TypeScript.

Cela permettrait d'importer des modules TypeScript dans le code TypeScript sans avoir besoin de fichiers de saisie d.ts (il n'y aurait même pas besoin de les générer).

@chanon Je soulignais juste ce que vous devez faire pour que votre code fonctionne.

@sccolbert je vois merci.

Quelqu'un qui sait peut-il me dire si je dois créer un autre problème demandant cette fonctionnalité spécifique ?

Les principaux problèmes liés à la logique de résolution de module (autres que celui-ci) semblent être # 2338 qui est fermé et # 5039 qui semble concerner la prise en charge de la résolution de chemin de style SystemJS qui semble très complexe.

Cependant, une simple importation de style CommonJS, comme initialement demandé dans ce numéro, semble avoir été oubliée ? Au moins la partie sur typescript.main et les dossiers en tant que modules ?

Je ne comprends pas la nécessité d'avoir (et le désir d'avoir) des fichiers d.ts si le module et le module consommateur sont déjà écrits en TypeScript.

Ce n'est en fait pas très différent de l'importation d'un fichier TypeScript relativement ex.

Au lieu de devoir faire :
import * as lib from '../relative/path/to/typescriptFile.ts'

Ou:
import * as lib from '../../node_modules/myModule/index.ts'

Laissez simplement TSC être en mesure de trouver le fichier dactylographié à importer en utilisant la résolution de chemin node_modules normale. Et au moins autoriser l'importation de dossiers en tant que modules (avec un index.ts) afin que dans le deuxième exemple, je puisse faire :

import * as lib from 'myModule'

Ou est-ce à cause de "vous ne voulez pas vraiment compiler vos dépendances, vous voulez juste consommer leurs typages" ?

@chanon , le comportement que vous décrivez est ce qui est maintenant dans le maître. pouvez-vous essayer typescript@next ?

l'implémentation originale de # 2338 a ajouté quelques vérifications supplémentaires pour s'assurer qu'il s'agit d'un .d.ts, et c'est principalement pour la raison que vous avez mentionnée. vous ne voulez pas que les utilisateurs de votre package compilent vos "sources" à chaque invocation du compilateur et obtiennent une sortie différente en fonction de leurs options de compilateur, vous souhaitez uniquement partager vos typages.

Cependant, si vous construisez les deux packages, vous souhaiterez peut-être le faire lors de l'itération. La restriction a été supprimée dans #5278.

Veuillez consulter la page wiki pour partager les saisies via le package npm pour plus d'informations : https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

Merci pour vos précisions @mhegazy ! Je vais l'essayer.

@mhegazy Je viens d'essayer avec typescript@next , fonctionne comme prévu !

C'est bien!!

Et merci à tous d'avoir participé à ce sujet et aux problèmes connexes :+1 :

J'ai ajouté une mise à jour au texte du problème ci-dessus pour expliquer la manière dont cette fonctionnalité a été implémentée.

Au risque d'entrer dans un champ de mines, comment cela devrait-il fonctionner avec les anciens modules npm qui _n'ont pas_ de propriété typings dans package.json ? Essayer d'utiliser tape ou get-parameter-names avec typescript@next me fait exploser au visage car il est incapable de trouver ces paquets car ils n'ont pas ça propriété.

Bien sûr, ce ne sont pas des modules dactylographiés, mais je n'arrive pas à trouver de solution et cela verrouille une partie importante de l'écosystème npm.

@danpantry Habituellement, vous utiliseriez un fichier .d.ts normal écrit spécifiquement pour ce module. Le projet DefinitelyTyped contient des fichiers .d.ts pour de nombreux modules courants. Il existe un utilitaire tsd qui peut vous aider à installer et à gérer les fichiers .d.ts de DefinitelyTyped.

Vous pouvez utiliser des modules normaux sans taper en utilisant simplement la syntaxe normale commonjs require.

par exemple
var nom_module = require("nom_module")

@chanon se sent un peu un hack pour utiliser la syntaxe 'classique' require lors de l'utilisation de la syntaxe ES6 avec TypeScript afin que je puisse utiliser les dépendances JavaScript, mais merci. J'ai entendu parler de l'utilitaire tsd mais je ne sais pas comment cela serait pris en compte dans l'utilisation des importations ES6... à moins que je doive commencer à utiliser /// <reference path=... pour ces types de modules ?

Oui c'est une façon. Une autre façon consiste à utiliser les fichiers tsconfig.json et à placer votre fichier racine tsd.d.ts comme premier fichier.

Vous pouvez également être intéressé à lire ceci, couvrant tsd et les typages https://angularclass.com/the-state-of-typescript-packages/

@joewood merci pour l'info, la dernière fois que j'ai regardé dans le tapuscrit, c'était à l'époque des fichiers individuels .d.ts . excellent article

@chanon @danpantry Il est quelque peu regrettable que import foo = require('foo') (avec foo sous node_modules) ne fonctionne pas lorsque le package.json de foo n'a pas de typage.

@wmono eh bien, car peut-être que la syntaxe TypeScript 0.80 ou peut-être antérieure import foo = require('foo') était uniquement destinée à l'importation de modules avec des typages. S'il n'y avait pas de typage, vous utiliseriez var foo = require('foo') la place. Donc je dirais que c'est comme ça.

@chanon Pardonnez-moi; erreur de l'utilisateur. Il semblait que Webpack avait du mal avec le "nu" require mais le problème était ailleurs.

Désolé, quelqu'un peut-il clarifier pourquoi
var foo = require('foo');
Fonctionne pour un node_module standard sans typage mais
import foo from 'foo';
n'est-ce pas? Cela a-t-il été défini arbitrairement ? Je ne vois pas pourquoi ce dernier ne devrait pas fonctionner - peu m'importe que la bibliothèque JS externe ait ou non des typages.

Désolé, quelqu'un peut-il clarifier pourquoi
var foo = require('foo');
Fonctionne pour un node_module standard sans typage mais
importer foo depuis 'foo' ;
n'est-ce pas? Cela a-t-il été défini arbitrairement ? Je ne vois pas pourquoi ce dernier ne devrait pas fonctionner - peu m'importe que la bibliothèque JS externe ait ou non des typages.

@harangue parce que var require était l'une des syntaxes de module concurrentes (celle-ci étant commonjs et les autres dans la liste incluent amd ) qui était prise en charge _en dehors du système de vérification de type_. Si l'on veut utiliser le système de type, on ferait import require . Avec ES6 prenant le :hammer: et disant qu'une syntaxe (:ring:) pour les gouverner tous ... il est logique que cette syntaxe de module soit prise en charge par le système de vérification de type prête à l'emploi :rose:

@basarat Merci pour la clarification. Les icônes étaient également utiles. ;) Je ne sais toujours pas pourquoi la syntaxe ES6 impose la vérification de type. Qu'est-ce qui empêche le compilateur de dire - "oh, je n'ai trouvé aucune donnée de type pour ce module mais je vais quand même l'importer". Quels effets secondaires ce comportement (plutôt intuitif, IMO) entraînerait-il ?

C'est déroutant pour ceux (comme moi) qui viennent de ES6 à TypeScript. Je m'attendrais à ce que la syntaxe d'importation du module ES6 se comporte de la même manière dans TypeScript, mais hélas, cela ne fonctionne pas du tout pour la plupart des packages npm ...

mais hélas cela ne fonctionne pas du tout pour la plupart des packages npm...

@teohhanhui je suis confus. Pouvez-vous donner un exemple concret de ce que vous essayez de réaliser et quel code vous avez essayé d'y parvenir. C'est juste pour pouvoir t'aider :rose:

import koa from 'koa';

donne Cannot find module 'koa'. (2307) quand target vaut es6

koa est (bien sûr) dans node_modules

Cependant, koa ne publie pas les typages Typescript avec leur projet. Ceci est uniquement pour les packages qui publient un .d.ts avec leur projet et le listent dans leur package.json. Parce que koa ne le fait pas, vous voudrez en plus installer ces définitions de type à partir de Definitely Typed.

Cela semble être une mauvaise décision car on s'attendrait à ce que l'instruction import fonctionne comme dans les modules ES6 simples. (Oui, je sais, la plupart des packages npm sont des modules CommonJS, mais les prendre en charge ici serait toujours la chose sensée à faire.)

Je suis nouveau sur TypeScript donc j'ai probablement une mauvaise compréhension, mais les définitions de type ne sont-elles pas facultatives? Pourquoi ne puis-je pas importer le package sans la définition de type ? Je ne veux pas être obligé de rechercher/créer des définitions de type.

Le passage à la syntaxe d'importation du module TS hérité n'est pas une option car il n'est pas autorisé lors de l'utilisation de la cible es6 .

Je suis nouveau sur TypeScript donc j'ai probablement une mauvaise compréhension, mais les définitions de type ne sont-elles pas facultatives?

C'est faux. Les définitions de type _dans votre propre code_ peuvent être implicites, ce qui signifie que le compilateur Typescript le "découvrira". Vous ne passerez jamais une bibliothèque tierce via le compilateur Typescript, de sorte que le compilateur ne saura jamais quels sont ces types. Si vous envisagez d'utiliser du code tiers, vous devriez vraiment apprendre à utiliser Definitely Typed et l'outil tsd .

Qu'en est-il de cette réponse de @basarat ?

http://stackoverflow.com/a/27434010/1529493

Pourquoi les modules non-TypeScript sans définitions de type ne peuvent-ils pas être importés en tant que tels ?

Ils peuvent : const koa = require(‘koa’)

Le 21 janvier 2016, à 14h47, Teoh Han Hui [email protected] a écrit :

Pourquoi les modules sans définitions de type ne peuvent-ils pas être importés en tant que tels ?


Répondez directement à cet e-mail ou consultez-le sur GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

@bgrieder Je fais référence à la syntaxe d'importation ES6.

(c'est-à-dire que vous utilisez commonjs), sinon, utilisez la réponse declare var de Basarat

Le 21 janv. 2016, à 14:48, Bruno Grieder bruno. [email protected] a écrit :

Ils peuvent : const koa = require(‘koa’)

Le 21 janvier 2016, à 14h47, Teoh Han Hui < [email protected] [email protected] > a écrit :

Pourquoi les modules sans définitions de type ne peuvent-ils pas être importés en tant que tels ?


Répondez directement à cet e-mail ou consultez-le sur GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

Je pense que le point soulevé est que l'un des objectifs de TypeScript est que JS valide soit un TS valide. Pour la syntaxe du module ES6, TS doit le compiler avec ou sans la présence de déclarations de type. Sans déclaration de type, une instruction import devrait simplement se résoudre en any .

Je suis entièrement d'accord avec cela.

@Joe Wood 👍

Le 21 janvier 2016, à 14h52, Joe Wood [email protected] a écrit :

Je pense que le point soulevé est que l'un des objectifs de TypeScript est que JS valide soit un TS valide. Pour la syntaxe du module ES6, TS doit le compiler avec ou sans la présence de déclarations de type. Sans déclarations de type, une instruction d'importation devrait simplement être résolue en any.

Je suis entièrement d'accord avec cela.


Répondez directement à cet e-mail ou consultez-le sur GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173575301.

FWIW ce comportement (en s'attendant à ce que toutes les bibliothèques tierces soient saisies à l'avance) est ce qui me pousse à utiliser Flow over TypeScript. Bien que TypeScript ait un support IDE, s'attendre à ce que tout soit tapé à l'avance n'est pas vraiment raisonnable, surtout lorsqu'il existe de nombreuses bibliothèques qui :

  • Ne sont pas sur DefinitelyTyped
  • Ne pas avoir de dossier ./typings
  • Je n'ai pas le temps de le taper moi-même

Je préfère ne pas avoir à lutter contre quelque chose qui est censé aider mon développement.

@danpantry , pourquoi ne pas simplement déclarer votre point d'entrée lib comme n'importe lequel, et le compilateur s'en contentera:

declare var $: any;

C'est une solution de contournement. Mais je pense que ce serait une bonne idée pour TypeScript de respecter le code du module ES6 et de se replier gracieusement. Je ne vois pas de bonne raison pour laquelle une instruction d'importation ne peut pas revenir à any plutôt que de signaler une erreur si le module de niveau supérieur n'est pas typé.

Je préférerais que le compilateur échoue tôt et bruyamment (le comportement actuel), plutôt que de laisser les problèmes d'exécution se glisser inaperçus. Je préférerais avoir explicitement une ligne declare var foo: any pour indiquer "ce n'est pas sûr, et je sais ce que je fais".

Pourquoi ne pas simplement autoriser la syntaxe d'importation ES6 lorsqu'aucun typage n'est disponible et émettre un simple avertissement du compilateur indiquant que l'importation s'est résolue en any , au lieu d'une erreur « émission empêchant » ?

Le 21 janvier 2016, à 18h42, S. Chris Colbert [email protected] a écrit :

Je préférerais que le compilateur échoue tôt et bruyamment (le comportement actuel), plutôt que de permettre aux problèmes d'exécution de se glisser inaperçus. Je préférerais avoir explicitement un declare var foo: n'importe quelle ligne pour indiquer "ce n'est pas sûr, et je sais ce que je fais".


Répondez directement à cet e-mail ou consultez-le sur GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173649845.

Dans tous les cas, le compilateur prétend actuellement qu'il ne peut pas trouver le module, alors qu'en réalité, il refuse simplement d'importer le module sans définition de type. Ce n'est pas vraiment utile, n'est-ce pas ?

^^^ Cela mille fois. Rien n'indiquait que je faisais quelque chose de mal lorsque j'ai rencontré ce problème pour la première fois. Il a fallu une longue recherche sur Google pour enfin comprendre ce qui se passait (d'ailleurs, je pense que ce problème est l'un des seuls endroits trouvables qui le documente). C'est tellement inutile. Et avec Angular 2 apportant TypeScript plus dans le courant dominant, je ne peux qu'imaginer combien de questions Stack Overflow proviendront de ce comportement.

Tout à fait d'accord avec la mauvaise description de la gestion des erreurs et importez-la simplement comme n'importe quoi!

@sccolbert Je suis d'accord qu'il devrait y avoir une notification mais je ne suis pas sûr que ce soit un échec - un avertissement à la place, peut-être

Je suis d'accord avec @mhegazy et @sccolbert.

Je préférerais de loin que nos scripts de construction de production (c'est-à-dire le serveur CI) se plaignent bruyamment si quelque chose ne va pas.

Salut les gars,
Ce comportement me rend juste fou. Les fichiers de définition ne sont pas à jour ou ne sont pas enregistrés dans package.json .
En fin de compte, TypeScript produit JavaScript , donc, jusqu'à ce que nous allions tous dans cette langue, soyez gentil avec le reste du monde qui fournit des bibliothèques pour la langue maternelle dans toutes les autres langues transpilées, comme la vôtre .
Je veux vraiment savoir si TypeScript veut rester (je dirais "s'intégrer" car il n'y paraît pas encore) dans l'écosystème JavaScript ou veut vivre une vie à part, comme la deuxième option me fera passer à autre chose.
Pour y parvenir un switch dans le fichier .tsconfig fera l'affaire, pour cela nous pouvons dire que nous voulons des importations strictes ou non.
En ce qui concerne la plainte bruyante de CI, il existe des cadres de test pour cela dans JavaScript . Quoi qu'il en soit, vous n'obtiendrez pas de vérification de type au moment de l'exécution, la mauvaise vérification de l'importation est le problème le moins important à avoir.
Tous mes vœux.

@devel-pa, les erreurs sont destinées à vous dire que le compilateur n'a aucune idée de ce qu'est votre importation. toute utilisation ultérieure de l'importation ne peut pas être vérifiée.

La désactivation des erreurs ne résout aucun problème. il pousse simplement ces "inconnues" silencieusement dans tout votre système. sans information de type, le compilateur ne peut pas vous avertir de ce qui est sûr et de ce qui ne l'est pas. et c'est tout l'intérêt de TypeScript :)

Quant au JS généré. aucune des erreurs de type TS n'empêche la génération de votre sortie. si vous ne vous souciez pas des erreurs de type, ignorez-les toutes. le compilateur génère toujours vos fichiers .js correspondants.

La solution pour les définitions manquantes est de les déclarer. vous n'avez pas besoin d'avoir la forme complète du module déclarée, mais juste le nom. Cela permet au compilateur de savoir qu'il existe un module "myLibrary", il peut vous avertir des fautes de frappe dans les noms de module, et plus important encore, aucun autre module ne serait décoché.

declare module "myLibrary" {
    var a: any;
    export = a;
}

comme indiqué dans # 6615, TypeScript devrait bientôt prendre en charge une forme plus courte.

Je pense que le problème est la douleur que cela cause pour les projets d'intégration. Je pense que ce problème est analogue à implicite any . À l'heure actuelle, ces importations sont essentiellement des vides implicites . Bien sûr, les erreurs peuvent être ignorées, mais cela cause beaucoup de bruit et va à l'encontre de la philosophie de typage progressif et valide JS est valide TS.

Je peux comprendre la confusion ici pour les personnes qui découvrent TS. S'ils ont activement utilisé la syntaxe du module ES6 dans JS, pourquoi cela ne fonctionne-t-il pas uniquement dans TS ? Quelle est la particularité de import from sur var x = require - qui _est_ traité comme un quelconque implicite. À l'origine, import était un mot clé spécifique à TS, ce qui impliquait que le développeur souhaitait que le module soit traité comme un module typé. Maintenant que ce n'est pas exclusif à TS, je ne pense pas que cette hypothèse puisse être faite.

les erreurs implicites-toutes sont sur les déclarations de variables sans type. mais l'utilisation d'une variable non déclarée est toujours une erreur aujourd'hui. Pour jquery, vous avez toujours besoin declare var $; quelque part pour que le compilateur sache que vous vouliez vraiment avoir une variable globale appelée $ et pas seulement mal tapée. c'est plus ou moins la même chose pour les modules, le compilateur doit savoir qu'il existe un module appelé "myLibrary" et que ce n'est pas un nom mal typé. il suffit donc d'ajouter une déclaration pour cela.

dans tous les cas, # 6615 devrait prendre en charge l'ajout declare module "*"; pour correspondre à tous les modules de votre système, bien que je pense que si vous faites cela, vous n'obtenez aucune aide de votre outillage et vous vous préparez à un douloureux transition plus tard lorsque vous décidez de le supprimer.

@mhegazy je comprends ton raisonnement mais j'ai vraiment un problème avec ce raisonnement

Fondamentalement, vous nous dites de concevoir une définition de module "espace réservé", et le problème disparaîtra.
Ce risque est qu'après un certain temps, sur un projet de taille raisonnable, ces définitions "d'espace réservé" peuvent simplement remonter et être enterrées dans un répertoire de typages. N'ayant plus d'avertissements, tout le monde les oubliera et lorsqu'un problème survient, parcourir chaque définition de module pour voir lequel est un espace réservé, va être pénible.

La situation est encore pire avec les modules typés (ceux avec l'entrée typings dans package.json) que nous supposons être correctement typés pourraient en fait utiliser ces espaces réservés en interne.

Je comprends que ces espaces réservés ne peuvent pas être empêchés, mais je préférerais de loin qu'au moins, ils ne soient pas encouragés.
Ce qu'il faut préconiser, c'est que par défaut, l'import se résolve en any et que le compilateur émette un avertissement à chaque compilation. Donc, au moins, en regardant les journaux du compilateur/CI, nous savons que quelque chose est potentiellement louche et doit être amélioré.

(en plus, comme indiqué sur la page d'accueil de typescriptlang.org, Typescript est un "surensemble" de Javascript, et à mon humble avis, toute syntaxe ES6 valide doit être avalée telle quelle)

Les solutions de contournement et le fait de cacher les ordures sous le tapis sont pour moi le pire qui puisse arriver (à côté de l'ES6 super).
Je travaille tout le temps avec des bibliothèques JS, et généralement avec les dernières versions dans le cadre de mon travail et du codage supplémentaire à la maison. 90% ne sont pas typés ou ont d'anciens defs, 9% ne sont pas très bien typés (car le compilateur ne sait pas faire un def pour tous les fichiers). Ni les miens n'ont de très bons defs, pour la même raison précédente et pour la raison que ma cible est JS, je ne pense pas avoir à me soucier de la langue d'origine.
De plus, j'ai vu la raison pour laquelle il existe des bibliothèques "inconnues". Non, pas du tout, si les développeurs ne savent pas et ne comprennent pas quelles bibliothèques sont utilisées, pourquoi s'en soucier, je sais pourquoi j'utilise des trucs et pourquoi j'ajoute à la pile. Des avertissements et des tests (si cela existe) suffisent pour cela.
Pls, JavaScript d'abord, c'est la cible et l'écosystème. TS n'est qu'un accessoire pour un meilleur codage et une meilleure vérification de type au moment de la compilation, mais uniquement pour ce que nous construisons. Le reste n'est pas une affaire de tapuscrits.
Je tiens à mentionner que j'étais aussi contre nmps peerDependencies , c'est moi qui ai choisi, pas le logiciel. Programmation impérative, bébé.

qu'en est-il de l'importation de modules à partir du répertoire JSPM au lieu de node_modules ?

edit : j'ai trouvé un ticket existant -> https://github.com/Microsoft/TypeScript/issues/6012

Je viens de rencontrer un problème avec la résolution du module Node, lors de l'utilisation de SystemJS pour charger un répertoire :

Apparemment, alors que Node (et donc TypeScript) comprend que le chemin est en fait un répertoire et charge donc index.ts la place, SystemJS ne fait rien de tel, ce qui signifie que le code TS valide ne se chargera pas dans le navigateur.

Cela est également vrai pour les modules de nœud qui ont un point d'entrée index.ts/js ou qui utilisent même la propriété package.json main . C'est un peu plus facile à utiliser, car il est facile (bien que répétitif) d'ajouter une configuration de package à SystemJS. Ce n'est pas si facile lorsque vous travaillez avec des répertoires arbitraires.

Quelle est la solution appropriée pour cela?

La résolution automatique des modules JSPM n'est pas prise en charge actuellement. ceci est suivi par https://github.com/Microsoft/TypeScript/issues/6012.

La recommandation est d'utiliser la prise en charge de la résolution du module de mappage de chemin, voir https://github.com/Microsoft/TypeScript-Handbook/blob/release-2.0/pages/Module%20Resolution.md#path -mapping

Les instructions ci-dessus sont un début, mais certaines personnes peuvent avoir besoin de faire quelque chose de plus... Vous devrez peut-être ajouter
<Folder Include="node_modules" />
vers .njsproj

Plus d'informations

Je construisais avec gulp et j'avais TypeScriptCompileBlocked dans .nsproj. Pour résoudre les problèmes de débogage des points d'arrêt dans VS 15 Preview 5 (j'obtenais l'erreur "frame not in module") et les problèmes que j'avais avec intellisense, je devais ajouter à .njsproj . Ce répertoire était déjà là lorsque j'ai importé le projet, mais il était défini sur git-ignore. C'est ma théorie sur la raison pour laquelle Visual Studio l'a ignoré (peut-être devrait-il avoir une exception automatique pour node_modules ?)

Au-delà du débogage et du fonctionnement intellisense, j'ai également cessé de voir des erreurs intellisense au-delà des mêmes erreurs exactes que j'ai vues de gulp pendant sa construction, ce qui est attendu.

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