Sayangnya hal-hal ini saat ini tidak didokumentasikan dengan baik, tetapi bahkan jika Anda dapat membuatnya berfungsi, mari kita bahas konfigurasi Anda sehingga Anda memahami apa yang dilakukan setiap bagian dan bagaimana hal itu berkaitan dengan bagaimana proses skrip dan memuat pengetikan.
Pertama mari kita bahas kesalahan yang Anda terima:
error TS2688: Cannot find type definition file for 'lodash'.
Kesalahan ini sebenarnya tidak berasal dari impor atau referensi Anda atau upaya Anda untuk menggunakan lodash di mana pun di file ts Anda. Alih-alih, ini berasal dari kesalahpahaman tentang cara menggunakan properti typeRoots
dan types
, jadi mari kita bahas lebih detail tentang itu.
Hal tentang typeRoots:[]
dan types:[]
properti adalah bahwa mereka BUKAN cara tujuan umum untuk memuat *.d.ts
file declaration ( ) arbitrer .
Kedua properti ini secara langsung terkait dengan fitur TS 2.0 baru yang memungkinkan deklarasi pengemasan dan pemuatan pengetikan dari paket NPM .
Ini sangat penting untuk dipahami, bahwa ini hanya bekerja dengan folder dalam format NPM (yaitu folder yang berisi package.json atau index.d.ts ).
Default untuk typeRoots
adalah:
{
"typeRoots" : ["node_modules/@types"]
}
Secara default ini berarti bahwa skrip ketikan akan masuk ke node_modules/@types
folder dan mencoba memuat setiap sub-folder yang ditemukan di sana sebagai paket npm .
Penting untuk dipahami bahwa ini akan gagal jika folder tidak memiliki struktur seperti paket npm.
Inilah yang terjadi dalam kasus Anda, dan sumber kesalahan awal Anda.
Anda telah mengganti typeRoot menjadi:
{
"typeRoots" : ["./typings"]
}
Artinya, skrip ketikan sekarang akan memindai ./typings
folder untuk subfolder dan mencoba memuat setiap subfolder yang ditemukannya sebagai modul npm.
Jadi anggap saja Anda baru saja typeRoots
menyiapkan untuk diarahkan ./typings
tetapi belum memiliki types:[]
penyiapan properti apa pun . Anda mungkin akan melihat kesalahan ini:
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
Ini karena tsc
memindai ./typings
folder Anda dan menemukan sub-folder custom
dan global
. Kemudian mencoba menafsirkan ini sebagai pengetikan tipe paket npm, tetapi tidak ada index.d.ts
atau package.json
di folder ini dan Anda mendapatkan kesalahan.
Sekarang mari kita bicara sedikit tentang types: ['lodash']
properti yang Anda tetapkan. Apa fungsinya? Secara default, skrip ketikan akan memuat semua sub-folder yang ditemukannya dalam file typeRoots
. Jika Anda menentukan types:
properti, itu hanya akan memuat sub-folder tertentu.
Dalam kasus Anda, Anda menyuruhnya untuk memuat ./typings/lodash
folder tetapi tidak ada. Inilah mengapa Anda mendapatkan:
error TS2688: Cannot find type definition file for 'lodash'
Jadi mari kita meringkas apa yang telah kita pelajari. Ketik 2.0 diperkenalkan typeRoots
dan types
untuk memuat file deklarasi yang dikemas dalam paket npm . Jika Anda memiliki pengetikan khusus atau satu d.ts
file longgar yang tidak terdapat dalam folder yang mengikuti konvensi paket npm, maka kedua properti baru ini bukanlah yang ingin Anda gunakan. Typecript 2.0 tidak benar-benar mengubah cara penggunaannya. Anda hanya perlu memasukkan file-file ini dalam konteks kompilasi Anda dengan salah satu dari banyak cara standar:
Langsung memasukkannya ke dalam .ts
file:
///<reference path="../typings/custom/lodash.d.ts" />
Termasuk ./typings/custom/lodash.d.ts
di dalam files: []
properti Anda .
Termasuk ./typings/index.d.ts
di files: []
properti Anda (yang kemudian secara rekursif menyertakan pengetikan lainnya.
Menambahkan ./typings/**
keincludes:
Mudah-mudahan, berdasarkan diskusi ini Anda akan dapat mengetahui mengapa perubahan yang Anda lakukan terhadap tsconfig.json
barang-barang Anda berhasil kembali.
EDIT:
Satu hal yang lupa saya sebutkan adalah bahwa typeRoots
dan types
properti benar-benar hanya berguna untuk pemuatan otomatis deklarasi global.
Misalnya jika Anda
npm install @types/jquery
Dan Anda menggunakan tsconfig default, maka paket tipe jquery itu akan dimuat secara otomatis dan $
akan tersedia di semua skrip Anda tanpa harus melakukan lebih jauh ///<reference/>
atauimport
The typeRoots:[]
properti dimaksudkan untuk menambahkan lokasi tambahan dari mana jenis paket akan dimuat frrom otomatis.
Kasus types:[]
penggunaan utama properti adalah menonaktifkan perilaku pemuatan otomatis (dengan menyetelnya ke array kosong), lalu hanya mencantumkan jenis tertentu yang ingin Anda sertakan secara global.
Cara lain untuk memuat paket tipe dari berbagai typeRoots
adalah dengan menggunakan ///<reference types="jquery" />
direktif baru . Perhatikan types
alih - alih path
. Sekali lagi, ini hanya berguna untuk file deklarasi global, biasanya file yang tidak berfungsi import/export
.
Nah, inilah salah satu hal yang menyebabkan kebingungan typeRoots
. Ingat, saya katakan itu typeRoots
tentang penyertaan global modul. Tetapi @types/folder
juga terlibat dalam resolusi modul standar (terlepas dari typeRoots
pengaturan Anda ).
Secara khusus, secara eksplisit mengimpor modul selalu melewati semua includes
, excludes
, files
, typeRoots
dan types
pilihan. Jadi, saat Anda melakukannya:
import {MyType} from 'my-module';
Semua properti yang disebutkan di atas sepenuhnya diabaikan. Sifat-sifat yang relevan selama resolusi modul yang baseUrl
, paths
, dan moduleResolution
.
Pada dasarnya, ketika menggunakan node
resolusi modul, itu akan mulai mencari untuk nama file my-module.ts
, my-module.tsx
, my-module.d.ts
mulai dari folder yang ditunjuk oleh Anda baseUrl
konfigurasi.
Jika tidak menemukan file tersebut, maka ia akan mencari folder bernama my-module
dan kemudian mencari a package.json
dengan typings
properti, jika ada package.json
atau tidak ada typings
properti di dalamnya yang memberi tahu file mana yang akan dimuat kemudian akan mencari di index.ts/tsx/d.ts
dalam folder itu.
Jika itu masih tidak berhasil, ia akan mencari hal-hal yang sama di node_modules
folder mulai dari Anda baseUrl/node_modules
.
Selain itu, jika tidak menemukannya, ia akan mencari baseUrl/node_modules/@types
semua hal yang sama.
Jika masih tidak menemukan apa pun, ia akan mulai masuk ke direktori induk dan mencari node_modules
dan di node_modules/@types
sana. Ini akan terus naik direktori sampai mencapai root sistem file Anda (bahkan mendapatkan modul-node di luar proyek Anda).
Satu hal yang ingin saya tekankan adalah resolusi modul sepenuhnya mengabaikan apa pun yang typeRoots
Anda tetapkan. Jadi jika Anda mengkonfigurasi typeRoots: ["./my-types"]
, ini tidak akan dicari selama resolusi modul eksplisit. Ini hanya berfungsi sebagai folder tempat Anda dapat meletakkan file definisi global yang ingin Anda sediakan untuk seluruh aplikasi tanpa perlu mengimpor atau referensi lebih lanjut.
Terakhir, Anda dapat mengganti perilaku modul dengan pemetaan jalur (misalnya paths
properti). Jadi misalnya, saya menyebutkan bahwa kebiasaan apa pun typeRoots
tidak dikonsultasikan saat mencoba menyelesaikan modul. Tetapi jika Anda suka, Anda dapat membuat perilaku ini terjadi sebagai berikut:
"paths" :{
"*": ["my-custom-types/*", "*"]
}
Apa yang dilakukannya adalah untuk semua impor yang cocok dengan sisi kiri, coba ubah impor seperti di sisi kanan sebelum mencoba untuk memasukkannya ( *
sisi kanan mewakili string impor awal Anda. Misalnya jika Anda mengimpor:
import {MyType} from 'my-types';
Ini akan mencoba impor terlebih dahulu seolah-olah Anda telah menulis:
import {MyType} from 'my-custom-types/my-types'
Dan kemudian jika tidak menemukannya akan mencoba lagi tanpa awalan (item kedua dalam larik hanya *
yang berarti impor awal.
Jadi dengan cara ini Anda dapat menambahkan folder tambahan untuk mencari file deklarasi kustom atau bahkan .ts
modul kustom yang Anda inginkan import
.
Anda juga dapat membuat pemetaan khusus untuk modul tertentu:
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
Ini akan membiarkan Anda melakukannya
import {MyType} from 'my-types';
Tapi kemudian baca jenis itu dari some/custom/folder/location/my-awesome-types-file.d.ts
paths
dan apa bedanyainclude
dengan tujuan pengetikan?"paths" :{ "my-types": ["some/custom/folder/location/my-awesome-types-file"] }
?Edit: kedaluwarsa. Baca jawabannya di atas.
Saya masih tidak mengerti ini, tetapi saya menemukan solusinya. Gunakan yang berikut ini
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" ] }
Hapus
typings.json
dan semua yang ada di bawah foldertypings
kecualilodash.d.ts
. Hapus juga semua///...
referensisumber
"*": ["./types/*"]
Baris ini di jalur tsconfig memperbaiki semuanya setelah perjuangan 2 jam.{ "compilerOptions": { "moduleResolution": "node", "strict": true, "baseUrl": ".", "paths": { "*": ["./types/*"] }, "jsx": "react", "types": ["node", "jest"] }, "include": [ "client/**/*", "packages/**/*" ], "exclude": [ "node_modules/**/*" ] }
jenis adalah nama folder, yang berada di samping node_module yaitu di tingkat folder klien (atau folder src )
types/third-party-lib/index.d.ts
index.d.ts memiliki
declare module 'third-party-lib';
Catatan: Konfigurasi di atas adalah konfigurasi yang tidak lengkap, hanya untuk memberikan gambaran tentang tampilannya dengan jenis, jalur, sertakan dan kecualikan di dalamnya.
sumber
Saya tahu ini adalah pertanyaan lama, tetapi perkakas jenis skrip terus berubah. Saya pikir opsi terbaik saat ini hanya mengandalkan pengaturan jalur "sertakan" di tsconfig.json.
"include": [ "src/**/*" ],
Secara default, kecuali Anda membuat perubahan tertentu, semua file * .ts dan semua * .d.ts di bawah
src/
akan disertakan secara otomatis. Saya pikir ini adalah cara termudah / terbaik untuk menyertakan file deklarasi tipe kustom tanpa penyesuaiantypeRoots
dantypes
.Referensi:
sumber