Cách để VS Code/TypeScript gợi ý tự động hoàn thành mà không cần nhập thư viện
Nếu một module (ví dụ moment.js, knockout, hoặc big.js) được bao gồm bằng thẻ <script> ví dụ.
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js">
</script>
định nghĩa một thuộc tính toàn cục (ví dụ: moment, ko, Big, v.v.), làm thế nào để một người có thể truy cập/khai báo các kiểu trên window (hoặc global) trong Typescript.
Ví dụ
const x = moment()
const t = ko.observable()
const b = new Big()
Làm thế nào để người ta có thể thiết lập kiểu ambient của các biến toàn cục này mà không cần bao gồm toàn bộ thư viện moment.js? Mục tiêu là có các tham chiếu toàn cục được gõ kiểu đúng để có thể sử dụng bởi VS Code, và tsc, ts-loader, hoặc babel-typescript.
Trong trường hợp của moment, các kiểu được hiển thị tại node_modules/moment/moment.d.ts, nhưng đối với các thư viện khác (ví dụ knockout hoặc big.js) thì chúng nằm ở @types/[module]/index.d.ts.
Cảm giác như điều này sẽ khá phổ biến, nhưng tôi chưa thấy một tài liệu tham khảo tốt, hoạt động về cách thực hiện điều này.
Đây là tsconfig:
{
"compilerOptions": {
"target": "ESNext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"strict": false,
"isolatedModules": false,
"esModuleInterop": true,
"noResolve": false,
"baseUrl": ".",
"paths": {
"*": [
"*",
"js.packages/*"
]
},
"jsx": "preserve",
"outDir": "dist/"
},
"include": [
"js.packages/**/*.ts",
"js.packages/**/*.tsx",
"js.packages/@types/lib.d.ts",
],
"files": [
"services/app/src/entry.js"
],
"exclude": [
"node_modules"
]
}
Đây là lib.d.ts
declare global {
type Bigable = Big | string | number
interface Window {
Big: typeof import('big.js'),
moment: typeof import('moment'),
Sentry: typeof import('@sentry/browser'),
}
}
và đây là cách tiêu thụ nên hoạt động:
const v = new Big(1)
const m = moment()
const s = global.Sentry()
const o = ko.observable()
trông như thế này trong VS Code (với gạch chân màu đỏ chỉ ra các lỗi):
Vì vậy knockout hoạt động vì @types/knockout/index.d.ts có:
declare var ko: KnockoutStatic;
declare module "knockout" {
export = ko;
}
trong khi tôi cũng đã khai báo một Big toàn cục trên interface Window.
Thật không may, Sentry và moment (trong ví dụ này) dường như không hoạt động, và không rõ lý do tại sao hoặc cần làm gì để sửa điều này.
Câu trả lời #1
Bạn có ý tưởng đúng, bạn cần sử dụng kiểu import để lấy các kiểu trong một import, bạn cần khai báo biến trong global. Vấn đề là bạn đang khai báo các thuộc tính trên Window. Mặc dù bất kỳ khóa nào được gán cho Window trở thành biến toàn cục, TypeScript không phản ánh điều này. Bạn có thể khai báo các biến trực tiếp trong phạm vi toàn cục.
declare global {
export var moment: typeof import('moment');
export var Sentry: typeof import('@sentry/browser');
}
const m = moment()
Sentry.init({}) // Sentry() does not seem like it should work according to docs
Câu trả lời #2
Câu hỏi không quá cụ thể cho một loại nền tảng nào, nhưng tôi sẽ nói với bạn cách tôi làm moment hoạt động trong Angular.
Trước tiên, bạn không nên tải từ một URL script. Bạn nên chạy npm install moment để đưa nó vào thư mục node_modules của bạn. Điều này sẽ đảm bảo nó được đóng gói vào phiên bản rút gọn của ứng dụng của bạn. Bạn không phải làm, nhưng điều này được khuyến nghị mạnh mẽ.
"scripts": [
"node_modules/jquery/dist/jquery.slim.min.js",
"node_modules/moment/moment.js",
...
]
Bất kể những điều trên, một khi bạn đã liên kết tập lệnh trong tsconfig (hoặc angular.json), việc sử dụng đơn giản như dòng sau ở đầu tệp:
import * as moment from 'moment';Tôi có xu hướng sử dụng cú pháp này cho hầu hết các thư viện có một đối tượng, ví dụ: shortid, linq và lodash.
Các thư viện khác hoạt động tốt hơn với các câu lệnh declare var. Ví dụ, tôi thấy jQuery hoạt động tốt hơn theo cách đó.
declare var $Gợi ý tự động
Nếu bạn đang tìm kiếm tính năng tự hoàn thành, bạn cần có một tệp .d.ts được nạp cho thư viện. Gói npm cho moment đi kèm với một tệp như vậy, nhưng một số thư viện cần phải cài đặt một gói npm khác cho việc này (ví dụ @types/lodash, @types/jquery).
Tự động hoàn thành của Visual Studio dựa vào các tệp .d.ts để xác định các kiểu. Tài liệu hướng dẫn cấu hình tính năng này nằm ở đây, và có thể cấu hình được (xem ghi chú gần cuối trang).
