Thật không may, những điều này hiện không được ghi chép đầy đủ, nhưng ngay cả khi bạn có thể làm cho nó hoạt động, hãy xem qua cấu hình của bạn để bạn hiểu từng phần đang hoạt động như thế nào và nó liên quan như thế nào đến cách xử lý bảng chữ và tải các bản đánh máy.
Trước tiên, hãy xem lại lỗi bạn đang gặp phải:
error TS2688: Cannot find type definition file for 'lodash'.
Lỗi này thực sự không đến từ việc nhập hoặc tham chiếu của bạn hoặc việc bạn cố gắng sử dụng lodash ở bất kỳ đâu trong tệp ts của mình. Thay vào đó, nó đến từ sự hiểu lầm về cách sử dụng các thuộc tính typeRoots
và types
, vì vậy chúng ta hãy đi vào chi tiết hơn một chút về chúng.
Vấn đề typeRoots:[]
và types:[]
thuộc tính là chúng KHÔNG phải là cách có mục đích chung để tải *.d.ts
các tệp khai báo ( ) tùy ý .
Hai thuộc tính này liên quan trực tiếp đến tính năng TS 2.0 mới cho phép đóng gói và tải các khai báo nhập từ các gói NPM .
Điều này rất quan trọng cần hiểu, rằng chúng chỉ hoạt động với các thư mục ở định dạng NPM (tức là một thư mục chứa package.json hoặc index.d.ts ).
Giá trị mặc định typeRoots
là:
{
"typeRoots" : ["node_modules/@types"]
}
Theo mặc định, điều này có nghĩa là chỉ định kiểu sẽ đi vào node_modules/@types
thư mục và cố gắng tải mọi thư mục con mà nó tìm thấy ở đó dưới dạng gói npm .
Điều quan trọng là phải hiểu rằng điều này sẽ không thành công nếu một thư mục không có cấu trúc giống như gói npm.
Đây là những gì đang xảy ra trong trường hợp của bạn và là nguồn gốc của lỗi ban đầu của bạn.
Bạn đã chuyển typeRoot để trở thành:
{
"typeRoots" : ["./typings"]
}
Điều này có nghĩa là bản đánh máy bây giờ sẽ quét ./typings
thư mục cho thư mục con và cố gắng tải từng thư mục con mà nó tìm thấy dưới dạng mô-đun npm.
Vì vậy, giả sử bạn vừa typeRoots
thiết lập để trỏ đến ./typings
nhưng chưa types:[]
thiết lập thuộc tính nào . Bạn có thể sẽ thấy những lỗi sau:
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
Điều này là do tsc
đang quét ./typings
thư mục của bạn và tìm các thư mục con custom
và global
. Sau đó, nó đang cố gắng giải thích những điều này là kiểu nhập kiểu gói npm, nhưng không có index.d.ts
hoặcpackage.json
trong các thư mục này và do đó bạn gặp lỗi.
Bây giờ chúng ta hãy nói một chút về thuộc types: ['lodash']
tính bạn đang thiết lập. Điều này làm gì? Theo mặc định, typecript sẽ tải tất cả các thư mục con mà nó tìm thấy trong của bạn typeRoots
. Nếu bạn chỉ định mộttypes:
tính, nó sẽ chỉ tải các thư mục con cụ thể đó.
Trong trường hợp của bạn, bạn đang yêu cầu nó tải ./typings/lodash
thư mục nhưng nó không tồn tại. Đây là lý do tại sao bạn nhận được:
error TS2688: Cannot find type definition file for 'lodash'
Vì vậy, hãy tóm tắt những gì chúng ta đã học được. Typecript 2.0 được giới thiệu typeRoots
và types
để tải các tệp khai báo được đóng gói trong gói npm . Nếu bạn có các kiểu đánh máy tùy chỉnh hoặc d.ts
các tệp rời đơn lẻ không được chứa trong một thư mục theo quy ước gói npm, thì hai thuộc tính mới này không phải là thứ bạn muốn sử dụng. Typecript 2.0 không thực sự thay đổi cách chúng được sử dụng. Bạn chỉ cần đưa các tệp này vào ngữ cảnh biên dịch của mình theo một trong nhiều cách tiêu chuẩn:
Trực tiếp đưa nó vào một .ts
tệp:
///<reference path="../typings/custom/lodash.d.ts" />
Kể cả ./typings/custom/lodash.d.ts
trong files: []
tài sản của bạn .
Bao gồm ./typings/index.d.ts
trong thuộc tính của bạn files: []
(sau đó bao gồm đệ quy các kiểu đánh máy khác.
Thêm ./typings/**
vào của bạnincludes:
Hy vọng rằng, dựa trên cuộc thảo luận này, bạn sẽ có thể biết lý do tại sao những thay đổi mà bạn tức giận đối với tsconfig.json
những thứ bạn đã làm lại hoạt động trở lại.
BIÊN TẬP:
Một điều mà tôi quên đề cập đến là typeRoots
và types
bất động sản là thực sự chỉ hữu ích cho việc tự động tải của tờ khai toàn cầu.
Ví dụ nếu bạn
npm install @types/jquery
Và bạn đang sử dụng tsconfig mặc định, sau đó gói loại jquery đó sẽ được tải tự động và $
sẽ có sẵn trong tất cả các tập lệnh của bạn mà bạn phải thực hiện thêm bất kỳ thao tác nào ///<reference/>
hoặcimport
Các typeRoots:[]
tài sản có nghĩa là để thêm các địa điểm khác từ nơi loại gói sẽ được nạp frrom tự động.
Các types:[]
trường hợp sử dụng chính tài sản là để vô hiệu hóa các hành vi tải tự động (bằng cách đặt nó vào một mảng trống), và sau đó chỉ liệt kê các loại cụ thể mà bạn muốn bao gồm toàn cầu.
Cách khác để tải các gói loại từ các gói khác nhau typeRoots
là sử dụng ///<reference types="jquery" />
chỉ thị mới . Chú ý types
thay vì path
. Một lần nữa, điều này chỉ hữu ích cho các tệp khai báo chung, thường là những tệp không có import/export
.
Bây giờ, đây là một trong những thứ gây nhầm lẫn typeRoots
. Hãy nhớ rằng, tôi đã nói đó typeRoots
là về sự bao gồm toàn cầu của các mô-đun. Nhưng @types/folder
cũng liên quan đến độ phân giải mô-đun tiêu chuẩn (bất kể typeRoots
cài đặt của bạn là gì ).
Cụ thể, các module nhập khẩu rõ ràng luôn luôn bỏ qua tất cả includes
, excludes
, files
, typeRoots
và types
các tùy chọn. Vì vậy, khi bạn làm:
import {MyType} from 'my-module';
Tất cả các thuộc tính nêu trên hoàn toàn bị bỏ qua. Các thuộc tính có liên quan trong quá trình giải quyết mô-đun là baseUrl
, paths
, và moduleResolution
.
Về cơ bản, khi sử dụng node
độ phân giải module, nó sẽ bắt đầu tìm kiếm một tên file my-module.ts
, my-module.tsx
, my-module.d.ts
bắt đầu từ thư mục trỏ đến bởi bạn baseUrl
cấu hình.
Nếu nó không tìm thấy tệp, thì nó sẽ tìm kiếm một thư mục có tên my-module
và sau đó tìm kiếm package.json
một thuộc typings
tính, nếu có package.json
hoặc không có thuộc typings
tính bên trong cho nó biết tệp cần tải thì nó sẽ tìm kiếm index.ts/tsx/d.ts
trong thư mục đó.
Nếu vẫn không thành công, nó sẽ tìm kiếm những thứ tương tự trong node_modules
thư mục bắt đầu từ của bạn baseUrl/node_modules
.
Ngoài ra, nếu nó không tìm thấy những thứ này, nó sẽ tìm kiếm baseUrl/node_modules/@types
tất cả những thứ tương tự.
Nếu nó vẫn không tìm thấy bất cứ điều gì nó sẽ bắt đầu đi đến thư mục cha và tìm kiếm node_modules
và node_modules/@types
ở đó. Nó sẽ tiếp tục đi lên các thư mục cho đến khi nó đạt đến thư mục gốc của hệ thống tệp của bạn (thậm chí nhận được mô-đun nút bên ngoài dự án của bạn).
Một điều tôi muốn nhấn mạnh là độ phân giải mô-đun hoàn toàn bỏ qua bất kỳ điều gì typeRoots
bạn đặt. Vì vậy, nếu bạn đã định cấu hình typeRoots: ["./my-types"]
, điều này sẽ không được tìm kiếm trong quá trình phân giải mô-đun rõ ràng. Nó chỉ đóng vai trò là một thư mục nơi bạn có thể đặt các tệp định nghĩa chung mà bạn muốn cung cấp cho toàn bộ ứng dụng mà không cần nhập hoặc tham khảo thêm.
Cuối cùng, bạn có thể ghi đè hành vi mô-đun bằng ánh xạ đường dẫn (tức là thuộc paths
tính). Vì vậy, ví dụ, tôi đã đề cập rằng bất kỳ tùy chỉnh nào typeRoots
không được tham khảo khi cố gắng giải quyết một mô-đun. Nhưng nếu bạn thích, bạn có thể làm cho hành vi này xảy ra như vậy:
"paths" :{
"*": ["my-custom-types/*", "*"]
}
Điều này thực hiện đối với tất cả các lần nhập khớp với phía bên trái, hãy thử sửa đổi phép nhập như ở phía bên phải trước khi cố gắng đưa vào ( *
phía bên phải biểu thị chuỗi nhập ban đầu của bạn. Ví dụ: nếu bạn nhập:
import {MyType} from 'my-types';
Trước tiên, nó sẽ thử nhập như thể bạn đã viết:
import {MyType} from 'my-custom-types/my-types'
Và sau đó nếu nó không tìm thấy nó sẽ thử lại với tiền tố (mục thứ hai trong mảng chỉ *
có nghĩa là nhập ban đầu.
Vì vậy, bằng cách này, bạn có thể thêm các thư mục bổ sung để tìm kiếm các tệp khai báo tùy chỉnh hoặc thậm chí các .ts
mô-đun tùy chỉnh mà bạn muốn import
.
Bạn cũng có thể tạo ánh xạ tùy chỉnh cho các mô-đun cụ thể:
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
Điều này sẽ để bạn làm
import {MyType} from 'my-types';
Nhưng sau đó đọc những loại đó từ some/custom/folder/location/my-awesome-types-file.d.ts
paths
và khácinclude
với mục đích của việc đánh máy như thế nào?