繁體中文(香港)
  • typescript
  • javascript
  • nodejs
  • node_modules
  • module-augmentation

TypeScript 模組擴展與處理嵌套 JavaScript 文件

學習 TypeScript 中模組擴展的基本知識,以及如何為嵌套的 JavaScript 文件添加類型定義。

Gao
Gao
Founder

Stop wasting weeks on user auth
Launch secure apps faster with Logto. Integrate user auth in minutes, and focus on your core product.
Get started
Product screenshot

TypeScript 對 JavaScript 生態系統已經是非常有價值的補充,超過十年來,由於能夠為 JavaScript 代碼提供類型安全性而逐漸流行起來。

JavaScript 套件的類型

為了向後兼容性和靈活性,TypeScript 允許套件作者為他們的 JavaScript 套件提供類型定義。這些類型定義通常存儲在 "DefinitelyTyped" 儲存庫中。 你可以使用 @types 命名空間安裝這些類型定義,例如,@types/react 是 React 套件的類型定義。

安裝這些類型定義後,你可以自信地以類型安全性使用這些套件。這裡是一個定義 React 元件具有類型安全性的例子:

模組擴展

雖然大多數流行的 JavaScript 套件在 @types 範圍內已經有可用的類型定義,但一些套件可能缺乏類型定義或是已經過時。在這種情況下,TypeScript 提供了一個強大的功能名為 「模組擴展」來為這些套件添加類型定義。讓我們看看一個例子:

現在你可以在你的代碼中使用這個擴展的類型定義:

模組擴展不僅允許你為套件添加類型定義,還可以擴展現有的類型定義。例如,你可以為 window 對象添加一個新屬性:

並在你的代碼中使用它:

上一篇文章 中,我們討論了 React Router 庫中的一個類型問題,我們必須通過擴展和增強現有類型來克服這個影響,通過自定義聲明文件。

記住,當使用模組擴展時,通過仔細檢查 JavaScript 源代碼來確保類型定義的準確性是至關重要的。不正確的類型定義可能會導致運行時錯誤。在上面的例子中,window.foo 屬性必須是一個存在於 window 對象上的字串。

全局擴展

有時你可能會遇到引入全局變量的腳本,你可能希望為這些全局變量提供類型定義,以便在 TypeScript 代碼中使用。例如,如果你有一個設置了一個名為 __DEV__ 的全局變量的腳本:

你可以像這樣添加這個全局變量的類型定義:

現在你可以在你的 TypeScript 代碼中使用它:

通過結合模組擴展和全局擴展,你甚至可以為 JavaScript 原型擴展類型定義。然而,這通常不建議,因為它可能會污染全局範圍。

模組擴展的強大功能允許此類擴展,但要謹慎操作以防止全局範圍的污染。

嵌套 JavaScript 文件

在前面的例子中,我們假設導入可以通過套件的入口文件解決。然而,某些套件會導出嵌套的 JavaScript 文件,而沒有對應的類型定義。考慮一個名叫 foo 的套件,其結構如下:

foo 套件以 index.js 文件作為入口點,並且還導出 bar 目錄。

要擴展 foo 套件的類型定義,你可以創建一個 foo.d.ts 文件:

然而,如果你嘗試在 TypeScript 中導入 baz.js 文件,你會遇到錯誤:

要擴展 baz.js 文件的類型定義,你需要創建一個單獨的 baz.d.ts 文件:

這確保 TypeScript 可以定位模塊及其相關的類型定義:

為了保持有組織的類型定義,你可以在你的類型定義文件中模仿套件的結構:

這種方法使你的 TypeScript 代碼保持結構化和類型安全,即使在處理嵌套的 JavaScript 文件時也是如此。