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 typeRoots
et 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.ts
fichiers 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 typeRoots
est:
{
"typeRoots" : ["node_modules/@types"]
}
Par défaut, cela signifie que dactylographié ira dans le node_modules/@types
dossier 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 ./typings
dossier 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 typeRoots
configuration sur laquelle pointer ./typings
mais 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 tsc
scanne votre ./typings
dossier et trouve les sous-dossiers custom
et global
. Il essaie ensuite de les interpréter comme une saisie de type de package npm, mais il n'y a pas index.d.ts
ou package.json
dans 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/lodash
dossier 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 typeRoots
et types
pour le chargement des fichiers de déclaration emballés dans les packages npm . Si vous avez des typages personnalisés ou des d.ts
fichiers 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 .ts
fichier:
///<reference path="../typings/custom/lodash.d.ts" />
Y compris ./typings/custom/lodash.d.ts
dans votre files: []
propriété.
Y compris ./typings/index.d.ts
dans 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.json
choses fonctionnent à nouveau.
ÉDITER:
Une chose que j'ai oublié de mentionner est que typeRoots
et la types
proprié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 typeRoots
est d'utiliser la nouvelle ///<reference types="jquery" />
directive. Notez le types
au 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 typeRoots
s'agissait de l'inclusion globale de modules. Mais @types/folder
est également impliqué dans la résolution de module standard (quel que soit votre typeRoots
réglage).
Plus précisément, les modules explicitement importateurs contournements toujours tous includes
, excludes
, files
, typeRoots
et types
options. 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
, paths
et moduleResolution
.
En fait, lorsque vous utilisez la node
résolution du module, il commencera à chercher un nom de fichier my-module.ts
, my-module.tsx
, my-module.d.ts
au niveau du dossier pointé par votre baseUrl
configuration.
S'il ne trouve pas le fichier, il recherchera un dossier nommé my-module
, puis recherchera un package.json
avec une typings
propriété, s'il n'y a package.json
ou aucune typings
propriété à l'intérieur lui indiquant quel fichier charger, il recherchera alors index.ts/tsx/d.ts
dans ce dossier.
Si cela ne fonctionne toujours pas, il recherchera ces mêmes éléments dans le node_modules
dossier en commençant par votre baseUrl/node_modules
.
De plus, s'il ne les trouve pas, il recherchera baseUrl/node_modules/@types
toutes les mêmes choses.
S'il ne trouve toujours rien, il commencera à aller dans le répertoire parent et à rechercher node_modules
et node_modules/@types
là. 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 typeRoots
ce 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 paths
propriété). Ainsi, par exemple, j'ai mentionné qu'aucune coutume typeRoots
n'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 .ts
modules 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
paths
et en quoi diffère-t-il desinclude
fins de frappe?