繁體中文(台灣)
  • typescript
  • javascript
  • nodejs
  • node_modules
  • module-augmentation

TypeScript 模組增強與處理巢狀 JavaScript 檔案

學習 TypeScript 中模組增強的基礎,以及如何為巢狀的 JavaScript 檔案添加型別定義。

Gao
Gao
Founder

不要在使用者認證上浪費數週時間
使用 Logto 更快地發布安全應用程式。幾分鐘內整合使用者認證,專注於您的核心產品。
立即開始
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 檔案

在前面提到的例子中,我們假設可以通過套件的入口檔案來解析 import。但有些套件會匯出沒有對應型別定義的巢狀 JavaScript 檔案。考慮一個名為 foo 的套件,其結構如下:

foo 套件匯出 index.js 檔案作為入口點,還匯出了 bar 目錄。

foo 套件增強型別定義,你可以創建一個 foo.d.ts 檔案:

然而,如果你嘗試在 TypeScript 中 import baz.js 檔案,你會遇到錯誤:

要為 baz.js 檔案增強型別定義,你需要創建一個單獨的 baz.d.ts 檔案:

這確保了 TypeScript 可以定位到模組及其關聯的型別定義:

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

這種方法即使在處理巢狀 JavaScript 檔案時,也能保持你的 TypeScript 程式碼結構化和型別安全。