Niestety, te rzeczy nie są obecnie dobrze udokumentowane, ale nawet jeśli udało ci się to uruchomić, przejdźmy do twojej konfiguracji, abyś zrozumiał, co robi każda część i jaki ma to związek z tym, jak maszynopis przetwarza i ładuje pisma.
Najpierw przyjrzyjmy się otrzymywanemu błędowi:
error TS2688: Cannot find type definition file for 'lodash'.
Ten błąd w rzeczywistości nie pochodzi z importu lub referencji ani z próby użycia lodash w dowolnym miejscu w plikach ts. Raczej wynika to z niezrozumienia, jak używać typeRoots
itypes
właściwości , więc przejdźmy do nich bardziej szczegółowo.
Chodzi o to, że właściwości typeRoots:[]
i NIEtypes:[]
są uniwersalnymi sposobami ładowania dowolnej deklaracji (*.d.ts
plików ).
Te dwie właściwości są bezpośrednio powiązane z nową funkcją TS 2.0, która umożliwia pakowanie i ładowanie deklaracji typowania z pakietów NPM .
Jest to bardzo ważne, aby zrozumieć, że działają one tylko z folderami w formacie NPM (tj. Folder zawierający plik package.json lub index.d.ts ).
Wartość domyślna typeRoots
to:
{
"typeRoots" : ["node_modules/@types"]
}
Domyślnie oznacza to, że maszynopis trafi do node_modules/@types
folderu i spróbuje załadować każdy podfolder, który tam znajdzie, jako pakiet npm .
Ważne jest, aby zrozumieć, że to się nie powiedzie, jeśli folder nie ma struktury podobnej do pakietu npm.
To właśnie dzieje się w twoim przypadku i jest źródłem twojego początkowego błędu.
Zmieniłeś typeRoot na:
{
"typeRoots" : ["./typings"]
}
Oznacza to, że maszynopis będzie teraz skanował ./typings
folder w poszukiwaniu podfolderów i spróbuje załadować każdy znaleziony podfolder jako moduł npm.
Załóżmy więc, że właśnie typeRoots
skonfigurowałeś ustawienia, na które chcesz wskazać, ./typings
ale nie masz jeszcze żadnych types:[]
ustawień właściwości. Prawdopodobnie zobaczysz te błędy:
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
Dzieje się tak, ponieważ tsc
skanuje twój ./typings
folder i znajduje podfoldery custom
i global
. Następnie próbuje zinterpretować je jako wpisywanie typu pakietu npm, ale nie ma tych folderów index.d.ts
lub package.json
w tych folderach, więc pojawia się błąd.
Porozmawiajmy teraz trochę o types: ['lodash']
ustawianej właściwości. Co to robi? Domyślnie maszynopis załaduje wszystkie podfoldery, które znajdzie w twoim typeRoots
. Jeśli określisz types:
właściwość, załadowane zostaną tylko te określone podfoldery.
W twoim przypadku mówisz mu, aby załadował ./typings/lodash
folder, ale nie istnieje. Dlatego otrzymujesz:
error TS2688: Cannot find type definition file for 'lodash'
Podsumujmy więc, czego się nauczyliśmy. Wprowadzono Typescript 2.0 typeRoots
i types
do ładowania plików deklaracji spakowanych w paczkach npm . Jeśli masz niestandardowe typy lub pojedyncze luźne d.ts
pliki, które nie są zawarte w folderze zgodnie z konwencjami pakietu npm, te dwie nowe właściwości nie są tym, czego chcesz użyć. Typescript 2.0 nie zmienia tak naprawdę sposobu ich wykorzystania. Musisz tylko uwzględnić te pliki w kontekście kompilacji na jeden z wielu standardowych sposobów:
Bezpośrednio dołączanie go do .ts
pliku:
///<reference path="../typings/custom/lodash.d.ts" />
W tym ./typings/custom/lodash.d.ts
w twojej files: []
nieruchomości.
Uwzględnianie ./typings/index.d.ts
w Twojej files: []
własności (która następnie rekurencyjnie obejmuje inne typy.
Dodawanie ./typings/**
doincludes:
Miejmy nadzieję, że na podstawie tej dyskusji będziesz w stanie powiedzieć, dlaczego zmiany, które oszalałeś w swoich tsconfig.json
stworzeniach, znów zadziałają.
EDYTOWAĆ:
Jedną rzeczą, o której zapomniałem wspomnieć, jest to, że typeRoots
i types
właściwości są naprawdę przydatne tylko do automatycznego ładowania deklaracji globalnych.
Na przykład jeśli ty
npm install @types/jquery
I używasz domyślnego tsconfig, wtedy ten pakiet typów jquery zostanie załadowany automatycznie i $
będzie dostępny we wszystkich twoich skryptach bez konieczności wykonywania dalszych czynności ///<reference/>
lubimport
typeRoots:[]
Nieruchomość jest przeznaczona, aby dodać kolejne lokalizacje, z których typ pakiety zostaną załadowane frrom automatycznie.
Przez types:[]
m.in. podstawowy use-case jest wyłączenie automatycznego ładowania zachowanie (poprzez ustawienie go na pustej tablicy), a następnie tylko wymieniając konkretne typy, które chcesz umieścić w skali globalnej.
Innym sposobem załadowania pakietów typów z różnych typeRoots
jest użycie nowej ///<reference types="jquery" />
dyrektywy. Zwróć uwagę na types
zamiast path
. Ponownie jest to przydatne tylko w przypadku plików deklaracji globalnych, zazwyczaj takich, które tego nie robią import/export
.
Oto jedna z rzeczy, które powodują zamieszanie z typeRoots
. Pamiętaj, powiedziałem, że typeRoots
chodzi o globalne włączenie modułów. Ale @types/folder
jest również zaangażowany w standardową rozdzielczość modułu (niezależnie od typeRoots
ustawień).
W szczególności, wyraźnie importowanie modułów zawsze omija wszystkie includes
, excludes
, files
, typeRoots
i types
opcje. Więc kiedy to zrobisz:
import {MyType} from 'my-module';
Wszystkie wyżej wymienione właściwości są całkowicie ignorowane. Odpowiednie właściwości podczas rozdzielczość modułu są baseUrl
, paths
i moduleResolution
.
Zasadniczo, przy użyciu node
rozdzielczość modułu, rozpocznie poszukiwania nazwy pliku my-module.ts
, my-module.tsx
, my-module.d.ts
zaczynając od katalogu wskazywanym przez baseUrl
konfiguracji.
Jeśli nie znajdzie pliku, będzie szukał folderu o nazwie, my-module
a następnie wyszuka właściwość package.json
z typings
właściwością, jeśli w środku jest właściwość package.json
lub jej nie ma, wskazując, typings
który plik ma załadować, a następnie wyszuka index.ts/tsx/d.ts
w tym folderze.
Jeśli to się nie powiedzie, wyszuka te same rzeczy w node_modules
folderze, zaczynając od twojego baseUrl/node_modules
.
Ponadto, jeśli ich nie znajdzie, wyszuka baseUrl/node_modules/@types
te same rzeczy.
Jeśli nadal nie znajdzie niczego, zacznie przechodzić do katalogu nadrzędnego i szukać node_modules
i node_modules/@types
tam. Będzie przechodzić w górę katalogów, aż dotrze do katalogu głównego systemu plików (nawet pobierze moduły węzłów poza projektem).
Chcę tylko podkreślić, że rozdzielczość modułu całkowicie ignoruje wszelkie typeRoots
ustawienia. Więc jeśli skonfigurowałeś typeRoots: ["./my-types"]
, to nie będzie przeszukiwane podczas jawnego rozwiązywania modułu. Służy tylko jako folder, w którym możesz umieścić globalne pliki definicji, które chcesz udostępnić całej aplikacji bez konieczności dalszego importowania lub odniesienia.
Na koniec możesz nadpisać zachowanie modułu za pomocą mapowania ścieżek (tj. paths
Właściwości). Na przykład wspomniałem, że typeRoots
przy próbie rozwiązania modułu nie jest konsultowany żaden zwyczaj . Ale jeśli ci się podobało, możesz to zrobić w następujący sposób:
"paths" :{
"*": ["my-custom-types/*", "*"]
}
W przypadku wszystkich importów, które pasują do lewej strony, spróbuj zmodyfikować import tak, jak po prawej stronie, zanim spróbujesz go uwzględnić ( *
po prawej stronie oznacza początkowy ciąg importu. Na przykład, jeśli importujesz:
import {MyType} from 'my-types';
Najpierw spróbuje importu, tak jakbyś napisał:
import {MyType} from 'my-custom-types/my-types'
A potem, jeśli nie znajdzie, spróbuje ponownie bez przedrostka (druga pozycja w tablicy to tylko *
to, co oznacza początkowy import.
W ten sposób możesz dodać dodatkowe foldery, aby wyszukać niestandardowe pliki deklaracji, a nawet niestandardowe .ts
moduły, które chcesz mieć import
.
Możesz również tworzyć niestandardowe mapowania dla określonych modułów:
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
To by ci pozwoliło
import {MyType} from 'my-types';
Ale potem przeczytaj te typy z some/custom/folder/location/my-awesome-types-file.d.ts
paths
i czym się różni odinclude
pisania na maszynie?"paths" :{ "my-types": ["some/custom/folder/location/my-awesome-types-file"] }
?Edycja: nieaktualne. Przeczytaj odpowiedź powyżej.
Nadal tego nie rozumiem, ale znalazłem rozwiązanie. Użyj następujących
tsconfig.json
:{ "compilerOptions": { "target": "ES6", "jsx": "react", "module": "commonjs", "sourceMap": true, "noImplicitAny": true, "experimentalDecorators": true, "baseUrl": ".", "paths": { "*": [ "./typings/*" ] } }, "include": [ "src/**/*" ], "exclude": [ "node_modules", "**/*.spec.ts" ] }
Usuń
typings.json
i wszystko w folderzetypings
opróczlodash.d.ts
. Usuń także wszystkie///...
odniesieniaźródło
"*": ["./types/*"]
Ta linia w ścieżkach tsconfig naprawiła wszystko po 2 godzinach walki.{ "compilerOptions": { "moduleResolution": "node", "strict": true, "baseUrl": ".", "paths": { "*": ["./types/*"] }, "jsx": "react", "types": ["node", "jest"] }, "include": [ "client/**/*", "packages/**/*" ], "exclude": [ "node_modules/**/*" ] }
typy to nazwa folderu, która znajduje się obok modułu_węzła, tj. na poziomie folderu klienta (lub folderu src )
types/third-party-lib/index.d.ts
index.d.ts ma
declare module 'third-party-lib';
Uwaga: powyższa konfiguracja jest niekompletną konfiguracją, aby pokazać, jak wygląda z typami, ścieżkami, włączaniem i wykluczaniem.
źródło
Wiem, że to stare pytanie, ale narzędzia maszynopisu ciągle się zmieniają. Myślę, że najlepszą opcją w tym momencie jest po prostu poleganie na ustawieniach ścieżki „include” w tsconfig.json.
"include": [ "src/**/*" ],
Domyślnie, o ile nie wprowadzisz określonych zmian, wszystkie pliki * .ts i wszystkie * .d.ts w ramach
src/
zostaną automatycznie uwzględnione. Myślę, że jest to najłatwiejszy / najlepszy sposób na dołączenie plików deklaracji typu niestandardowego bez dostosowywaniatypeRoots
itypes
.Odniesienie:
źródło