Sfortunatamente queste cose non sono attualmente molto ben documentate, ma anche se sei riuscito a farlo funzionare, esaminiamo la tua configurazione in modo da capire cosa sta facendo ogni parte e come si relaziona a come il dattiloscritto elabora e carica le battiture.
Per prima cosa esaminiamo l'errore che stai ricevendo:
error TS2688: Cannot find type definition file for 'lodash'.
Questo errore in realtà non proviene dalle tue importazioni o riferimenti o dal tuo tentativo di utilizzare lodash ovunque nei tuoi file ts. Piuttosto deriva da un malinteso su come utilizzare le proprietà typeRoots
e types
, quindi entriamo un po 'più in dettaglio su quelle.
Il problema delle proprietà typeRoots:[]
e types:[]
è che NON sono modi generici per caricare *.d.ts
file di dichiarazione arbitrari ( ).
Queste due proprietà sono direttamente correlate alla nuova funzionalità TS 2.0 che consente la creazione di pacchetti e il caricamento di dichiarazioni di digitazione dai pacchetti NPM .
Questo è molto importante per capire che funzionano solo con cartelle in formato NPM (cioè una cartella contenente un package.json o index.d.ts ).
L'impostazione predefinita per typeRoots
è:
{
"typeRoots" : ["node_modules/@types"]
}
Per impostazione predefinita, questo significa che il dattiloscritto andrà nella node_modules/@types
cartella e proverà a caricare ogni sottocartella che trova lì come pacchetto npm .
È importante capire che questo fallirà se una cartella non ha una struttura simile a un pacchetto npm.
Questo è ciò che sta accadendo nel tuo caso e la fonte del tuo errore iniziale.
Hai cambiato typeRoot in:
{
"typeRoots" : ["./typings"]
}
Ciò significa che il dattiloscritto ora scansionerà la ./typings
cartella per le sottocartelle e proverà a caricare ogni sottocartella che trova come un modulo npm.
Quindi fingiamo che tu abbia appena avuto la typeRoots
configurazione a cui puntare ./typings
ma non hai ancora alcuna types:[]
configurazione della proprietà. Probabilmente vedrai questi errori:
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
Questo perché tsc
sta scansionando la tua ./typings
cartella e trovando le sottocartelle custom
e global
. Quindi sta cercando di interpretarli come una digitazione di tipo pacchetto npm, ma non c'è index.d.ts
o package.json
in queste cartelle e quindi viene visualizzato l'errore.
Ora parliamo un po 'della types: ['lodash']
proprietà che stai impostando. Cosa fa questo? Per impostazione predefinita, il dattiloscritto caricherà tutte le sottocartelle che trova all'interno del tuo file typeRoots
. Se specifichi una types:
proprietà, caricherà solo quelle specifiche sottocartelle.
Nel tuo caso gli stai dicendo di caricare la ./typings/lodash
cartella ma non esiste. Questo è il motivo per cui ottieni:
error TS2688: Cannot find type definition file for 'lodash'
Quindi riassumiamo ciò che abbiamo imparato. Typescript 2.0 introdotto typeRoots
e types
per caricare file di dichiarazione impacchettati in pacchetti npm . Se si dispone di digitazioni personalizzate o di singoli d.ts
file sciolti che non sono contenuti in una cartella secondo le convenzioni del pacchetto npm, queste due nuove proprietà non sono ciò che si desidera utilizzare. Typescript 2.0 non cambia realmente come questi verrebbero consumati. Devi solo includere questi file nel tuo contesto di compilazione in uno dei tanti modi standard:
Inserendolo direttamente in un .ts
file:
///<reference path="../typings/custom/lodash.d.ts" />
Compreso ./typings/custom/lodash.d.ts
nella tua files: []
proprietà.
Incluso ./typings/index.d.ts
nella tua files: []
proprietà (che quindi include ricorsivamente le altre digitazioni.
Aggiungendo ./typings/**
al tuoincludes:
Si spera che sulla base di questa discussione sarai in grado di dire perché i cambiamenti che hai tsconfig.json
fatto per le tue cose hanno funzionato di nuovo.
MODIFICARE:
Una cosa che ho dimenticato di menzionare è che typeRoots
e le types
proprietà sono davvero utili solo per il caricamento automatico delle dichiarazioni globali.
Ad esempio se tu
npm install @types/jquery
E stai usando il tsconfig predefinito, quindi quel pacchetto di tipi jquery verrà caricato automaticamente e $
sarà disponibile in tutti i tuoi script senza dover fare altro ///<reference/>
oimport
La typeRoots:[]
proprietà ha lo scopo di aggiungere ulteriori posizioni da cui verranno caricati automaticamente i pacchetti di tipo .
Il types:[]
caso d'uso principale della proprietà è disabilitare il comportamento di caricamento automatico (impostandolo su un array vuoto) e quindi elencare solo i tipi specifici che si desidera includere a livello globale.
L'altro modo per caricare i pacchetti di tipo dai vari typeRoots
è usare la nuova ///<reference types="jquery" />
direttiva. Notare il types
invece di path
. Di nuovo, questo è utile solo per i file di dichiarazione globale, tipicamente quelli che non lo fanno import/export
.
Ora, ecco una delle cose che causa confusione con typeRoots
. Ricorda, ho detto che typeRoots
riguarda l'inclusione globale dei moduli. Ma @types/folder
è anche coinvolto nella risoluzione del modulo standard (indipendentemente dalle typeRoots
impostazioni).
In particolare, i moduli in modo esplicito che importano bypassa sempre tutti includes
, excludes
, files
, typeRoots
e types
le opzioni. Quindi quando lo fai:
import {MyType} from 'my-module';
Tutte le proprietà sopra menzionate vengono completamente ignorate. Le proprietà rilevanti durante la risoluzione del modulo sono baseUrl
, paths
e moduleResolution
.
In sostanza, quando si utilizza node
la risoluzione del modulo, si inizierà a cercare un nome di file my-module.ts
, my-module.tsx
, my-module.d.ts
a partire dalla cartella a cui punta la vostra baseUrl
configurazione.
Se non trova il file, cercherà una cartella denominata my-module
e quindi cercherà una package.json
con una typings
proprietà, se non c'è package.json
o nessuna typings
proprietà all'interno che gli dice quale file caricare, cercherà index.ts/tsx/d.ts
all'interno di quella cartella.
Se il problema persiste, cercherà le stesse cose nella node_modules
cartella a partire da baseUrl/node_modules
.
Inoltre, se non li trova, cercherà baseUrl/node_modules/@types
tutte le stesse cose.
Se ancora non ha trovato nulla, inizierà ad andare nella directory principale, a cercare node_modules
e node_modules/@types
lì. Continuerà a risalire le directory fino a raggiungere la radice del file system (anche ottenendo i moduli del nodo al di fuori del progetto).
Una cosa che voglio sottolineare è che la risoluzione del modulo ignora completamente qualsiasi typeRoots
impostazione. Quindi, se hai configurato typeRoots: ["./my-types"]
, questo non verrà cercato durante la risoluzione esplicita del modulo. Serve solo come una cartella in cui è possibile inserire i file di definizione globale che si desidera rendere disponibili per l'intera applicazione senza ulteriore necessità di importazione o riferimento.
Infine, puoi sovrascrivere il comportamento del modulo con le mappature del percorso (cioè la paths
proprietà). Quindi, ad esempio, ho detto che qualsiasi custom typeRoots
non viene consultata quando si cerca di risolvere un modulo. Ma se ti è piaciuto puoi far sì che questo comportamento si verifichi in questo modo:
"paths" :{
"*": ["my-custom-types/*", "*"]
}
Ciò che fa è per tutte le importazioni che corrispondono al lato sinistro, prova a modificare l'importazione come nel lato destro prima di provare a includerlo (il *
lato destro rappresenta la stringa di importazione iniziale. Ad esempio, se importi:
import {MyType} from 'my-types';
Avrebbe prima provato l'importazione come se avessi scritto:
import {MyType} from 'my-custom-types/my-types'
E poi, se non lo trova, riprova senza il prefisso (il secondo elemento nell'array è proprio il *
che significa l'importazione iniziale.
Quindi in questo modo puoi aggiungere ulteriori cartelle per cercare file di dichiarazione personalizzata o anche .ts
moduli personalizzati che desideri essere in grado di creare import
.
Puoi anche creare mappature personalizzate per moduli specifici:
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
Questo ti lascerebbe fare
import {MyType} from 'my-types';
Ma poi leggi quei tipi da some/custom/folder/location/my-awesome-types-file.d.ts
paths
e in che modo è diverso rispettoinclude
ai fini della digitazione?