TypeScript 模組增強與處理巢狀 JavaScript 檔案
學習 TypeScript 中模組增強的基礎,以及如何為巢狀的 JavaScript 檔案添加型別定義。
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 程式碼結構化和型別安全。