使用 Typescript 聲明合併擴展 Expresss 請求對象。
在過去的幾年裡,Express 一直是我使用的服務器端節點 Web 框架。它快速、無主見且易於啟動和運行。我應該說,我也非常喜歡將它與 Typescript 一起使用。它提高了代碼質量和理解能力。在 Typescript 中重構代碼也更加容易和快捷。此外,在使用 Visual Studio Code 等現代文本編輯器時,您還可以獲得代碼完成和 IntelliSense 的額外優勢。 😋
我最近開始使用的 Typescript 的概念之一是 Declaration Merging
.
聲明合併允許您將兩個或多個不同的聲明或同名聲明的類型合併到一個定義中。這個概念允許您將自己的自定義屬性附加到另一個 Typescript 接口類型。我們來看一個典型的 Express 中間件。
上面的代碼是一個 Express 中間件,用於確保用戶在嘗試訪問受保護的資源時通過身份驗證。它從請求標頭的授權屬性中解碼用戶的令牌,並將用戶附加到請求對象。但是看到那條紅色的波浪線了嗎?
那是因為屬性 currentUser
Express 的 Request 接口類型上不存在。讓我們解決這個問題。 😃
我們需要做的第一件事是創建一個新的聲明文件@types > express > index.d.ts
在我們項目的根目錄中。
您會注意到這與我們的 node_modules/@types
中的文件名和路徑完全相同 文件夾。要使 Typescript 聲明合併生效,文件名及其路徑必須與原始聲明文件和路徑匹配。
接下來我們需要對項目的tsconfig.json
做一些改動 文件。讓我們更新 typeRoots
值如下:
...
"typeRoots": [
"@types",
"./node_modules/@types",
]
...
默認情況下,Typescript 編譯器在 node_modules/@types
中查找類型定義 文件夾。上面的代碼指示編譯器在這個文件夾中查找類型定義以及我們自定義的 @types
我們項目根目錄中的文件夾。
現在是時候添加我們的自定義 currentUser
通過修改index.d.ts
屬性為Express的Request接口類型 我們之前創建的文件:
import { UserModel } from "../../src/user/user.model";
declare global{
namespace Express {
interface Request {
currentUser: UserModel
}
}
}
讓我們再看看我們的中間件文件,我們立即註意到紅色波浪線消失了!這是因為 Typescript 編譯器現在可以識別 currentUser
屬性作為請求類型接口上的有效屬性。
祝大家編碼愉快!