Malheureusement, ces choses ne sont pas très bien documentées actuellement, mais même si vous avez pu le faire fonctionner, passons en revue votre configuration afin que vous compreniez ce que fait chaque partie et comment elle se rapporte à la façon dont le typographie traite et charge les typages.
Passons d'abord en revue l'erreur que vous recevez:
error TS2688: Cannot find type definition file for 'lodash'.
Cette erreur ne provient en fait pas de vos importations ou références ou de votre tentative d'utiliser lodash n'importe où dans vos fichiers ts. Cela vient plutôt d'un malentendu sur la façon d'utiliser les propriétés typeRootset types, alors allons-y un peu plus en détail.
Le problème typeRoots:[]avec les types:[]propriétés et c'est qu'elles ne sont PAS des moyens généraux de charger des *.d.tsfichiers de déclaration arbitraires ( ).
Ces deux propriétés sont directement liées à la nouvelle fonctionnalité TS 2.0 qui permet d'empaqueter et de charger des déclarations de typage à partir de packages NPM .
Il est très important de comprendre que ceux-ci ne fonctionnent qu'avec des dossiers au format NPM (c'est-à-dire un dossier contenant un package.json ou index.d.ts ).
La valeur par défaut pour typeRootsest:
{
"typeRoots" : ["node_modules/@types"]
}
Par défaut, cela signifie que dactylographié ira dans le node_modules/@typesdossier et essaiera de charger chaque sous-dossier qu'il y trouvera en tant que package npm .
Il est important de comprendre que cela échouera si un dossier n'a pas de structure de type package npm.
C'est ce qui se passe dans votre cas et la source de votre erreur initiale.
Vous avez changé de typeRoot pour être:
{
"typeRoots" : ["./typings"]
}
Cela signifie que dactylographié analysera maintenant le ./typingsdossier pour les sous-dossiers - et essayer de charger chaque sous-dossier qu'il trouve en tant que module npm.
Supposons donc que vous ayez juste une typeRootsconfiguration sur laquelle pointer ./typingsmais que vous n'avez pas encore de types:[]configuration de propriété. Vous verrez probablement ces erreurs:
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
En effet, il tscscanne votre ./typingsdossier et trouve les sous-dossiers customet global. Il essaie ensuite de les interpréter comme une saisie de type de package npm, mais il n'y a pas index.d.tsou package.jsondans ces dossiers et vous obtenez l'erreur.
Parlons maintenant un peu de la types: ['lodash']propriété que vous définissez. Qu'est ce que cela fait? Par défaut, dactylographié chargera tous les sous-dossiers qu'il trouve dans votre fichier typeRoots. Si vous spécifiez untypes: propriété, il ne chargera que ces sous-dossiers spécifiques.
Dans votre cas, vous lui dites de charger le ./typings/lodashdossier mais il n'existe pas. C'est pourquoi vous obtenez:
error TS2688: Cannot find type definition file for 'lodash'
Alors résumons ce que nous avons appris. Typescript 2.0 introduit typeRootset typespour le chargement des fichiers de déclaration emballés dans les packages npm . Si vous avez des typages personnalisés ou des d.tsfichiers lâches uniques qui ne sont pas contenus dans un dossier suivant les conventions de package npm, ces deux nouvelles propriétés ne sont pas ce que vous souhaitez utiliser. Typescript 2.0 ne change pas vraiment la façon dont ils seraient consommés. Il vous suffit d'inclure ces fichiers dans votre contexte de compilation de l'une des nombreuses manières standard:
L'inclure directement dans un .tsfichier:
///<reference path="../typings/custom/lodash.d.ts" />
Y compris ./typings/custom/lodash.d.tsdans votre files: []propriété.
Y compris ./typings/index.d.tsdans votre files: []propriété (qui inclut alors récursivement les autres typages.
Ajout ./typings/**à votreincludes:
Avec un peu de chance, sur la base de cette discussion, vous serez en mesure de dire pourquoi les changements que vous avez apportés à vos tsconfig.jsonchoses fonctionnent à nouveau.
ÉDITER:
Une chose que j'ai oublié de mentionner est que typeRootset la typespropriété n'est vraiment utile que pour le chargement automatique des déclarations globales.
Par exemple si vous
npm install @types/jquery
Et vous utilisez le tsconfig par défaut, alors ce package de types jquery sera chargé automatiquement et $sera disponible dans tous vos scripts sans avoir à faire plus ///<reference/>ouimport
La typeRoots:[]propriété est destinée à ajouter des emplacements supplémentaires à partir desquels les packages de types seront chargés automatiquement.
Le types:[]principal cas d'utilisation de la propriété consiste à désactiver le comportement de chargement automatique (en le définissant sur un tableau vide), puis à répertorier uniquement les types spécifiques que vous souhaitez inclure globalement.
L'autre façon de charger des packages de type à partir des différents typeRootsest d'utiliser la nouvelle ///<reference types="jquery" />directive. Notez le typesau lieu de path. Encore une fois, cela n'est utile que pour les fichiers de déclaration globale, généralement ceux qui ne le font pas import/export.
Maintenant, voici l'une des choses avec lesquelles il y a confusion typeRoots. N'oubliez pas, j'ai dit qu'il typeRootss'agissait de l'inclusion globale de modules. Mais @types/folderest également impliqué dans la résolution de module standard (quel que soit votre typeRootsréglage).
Plus précisément, les modules explicitement importateurs contournements toujours tous includes, excludes, files, typeRootset typesoptions. Alors quand vous faites:
import {MyType} from 'my-module';
Toutes les propriétés mentionnées ci-dessus sont complètement ignorées. Les propriétés pertinentes au cours de la résolution du module sont baseUrl, pathset moduleResolution.
En fait, lorsque vous utilisez la noderésolution du module, il commencera à chercher un nom de fichier my-module.ts, my-module.tsx, my-module.d.tsau niveau du dossier pointé par votre baseUrlconfiguration.
S'il ne trouve pas le fichier, il recherchera un dossier nommé my-module, puis recherchera un package.jsonavec une typingspropriété, s'il n'y a package.jsonou aucune typingspropriété à l'intérieur lui indiquant quel fichier charger, il recherchera alors index.ts/tsx/d.tsdans ce dossier.
Si cela ne fonctionne toujours pas, il recherchera ces mêmes éléments dans le node_modulesdossier en commençant par votre baseUrl/node_modules.
De plus, s'il ne les trouve pas, il recherchera baseUrl/node_modules/@typestoutes les mêmes choses.
S'il ne trouve toujours rien, il commencera à aller dans le répertoire parent et à rechercher node_moduleset node_modules/@typeslà. Il continuera à remonter dans les répertoires jusqu'à ce qu'il atteigne la racine de votre système de fichiers (même en obtenant des modules de nœuds en dehors de votre projet).
Une chose que je tiens à souligner est que la résolution du module ignore complètement tout typeRootsce que vous définissez. Donc, si vous avez configuré typeRoots: ["./my-types"], cela ne sera pas recherché pendant la résolution explicite du module. Il sert uniquement de dossier dans lequel vous pouvez placer les fichiers de définition globale que vous souhaitez mettre à la disposition de l'ensemble de l'application sans avoir à importer ou à référencer davantage.
Enfin, vous pouvez remplacer le comportement du module avec des mappages de chemins (c'est-à-dire la pathspropriété). Ainsi, par exemple, j'ai mentionné qu'aucune coutume typeRootsn'est consultée lors de la tentative de résolution d'un module. Mais si vous avez aimé, vous pouvez faire en sorte que ce comportement se produise comme suit:
"paths" :{
"*": ["my-custom-types/*", "*"]
}
Pour toutes les importations qui correspondent au côté gauche, essayez de modifier l'importation comme dans le côté droit avant d'essayer de l'inclure (le *côté droit représente votre chaîne d'importation initiale. Par exemple, si vous importez:
import {MyType} from 'my-types';
Il essaierait d'abord l'importation comme si vous aviez écrit:
import {MyType} from 'my-custom-types/my-types'
Et puis s'il ne le trouve pas, il essaiera à nouveau sans le préfixe (le deuxième élément du tableau est juste *ce qui signifie l'importation initiale.
Ainsi, vous pouvez ajouter des dossiers supplémentaires pour rechercher des fichiers de déclaration personnalisés ou même des .tsmodules personnalisés que vous souhaitez pouvoir utiliser import.
Vous pouvez également créer des mappages personnalisés pour des modules spécifiques:
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
Cela vous permettrait de faire
import {MyType} from 'my-types';
Mais alors lisez ces types de some/custom/folder/location/my-awesome-types-file.d.ts
pathset en quoi diffère-t-il desincludefins de frappe?