TypeScript Express 錯誤函數
在 TypeScript 編程中,錯誤處理函數的四個參數類型是什麼?
app.use((err: ??, req: ??, res: ??, next: ??) => { });
我正在使用 VS Code,但沒有提供任何提示。我在所有四個參數下都看到紅色波浪線。
錯誤顯示「參數隱式具有 'any' 類型」。其實我對這個訊息感到困惑。如果它被當作 any 類型,難道這不是一個有效的選擇嗎?
答案#1
該函數本身具有以下簽名(摘自 DefinitelyTyped):
export type ErrorRequestHandler = (err: any, req: Request, res: Response, next: NextFunction) => any;
所以你可以將函數宣告為 ErrorRequestHandler 類型的變數,或者根據該定義對參數進行類型標註。
注意:「express-serve-static-core」的類型定義被「express」的類型定義導入並重新導出,而我就是在這裡查找上述定義。
import type { ErrorRequestHandler } from "express";
const errorHandler: ErrorRequestHandler = (err, req, res, next) => {};
app.use(errorHandler);
關於你第二個與隱式 any 有關的問題,問題出在「隱式」這部分。如果你明確地將類型寫為 any,那麼就不會有任何錯誤(但也不會有任何型別;可以考慮使用 unknown 代替)。
你也可以在你的編譯器配置中禁用 noImplicitAny,但我個人不建議這麼做,因為它可以保護你免受多種類型錯誤的影響。
答案#2
我不知道為什麼 Typescript 無法理解我們正在傳遞一個錯誤處理器。
這些是我認為可行的解決方案:
app.use((err, req, res, next) => {}) // KO
const inVariable : ErrorRequestHandler = (err, req, res, next) => {};
app.use(inVariable); // ok
app.use(((err, req, res, next) => {}) as ErrorRequestHandler); // ok
答案#3
自訂錯誤類型
完全使用 any 就放棄了 Typescript 的類型檢查優勢。因為在 JavaScript 中,可以 throw 任何東西,對於 err 參數,從 Typescript 3.0 開始可以使用類型 unknown:
app.use((err: unknown, req: Request, res: Response, next: NextFunction) => { })
例子
如果需要,可以像以下這樣創建自訂錯誤:
// HttpException.ts in exceptions directory of your project.
export class HttpException extends Error {
public status: number
public message: string
constructor(status: number, message: string) {
super(message)
this.status = status
this.message = message
}
}
然後在您使用它的任何地方導入自訂錯誤:
import { HttpException } from './exceptions/HttpException'
app.use((req: Request, res: Response, next: NextFunction) => {
const err = new HttpException(404, 'Not Found')
// Do something with error here...
next(err)
})
app.use((err: unknown, req: Request, res: Response, next: NextFunction) => {
if (err instanceof HttpException) {
// Do something more with the error here...
}
next(err)
})
因為 err 的類型是 unknown,我們無法直接訪問或修改 err。首先,我們需要使用 instanceof 來檢查類型,這樣結果會將 err 智能地轉型為該類型(在我們的例子中為 HttpException)。
我們可以根據需要隨時向 HttpException 類添加任何屬性和方法,就像我們添加了 status 和 message 一樣。
型別定義
如果你還沒有做的話,你需要為你的 Typescript 專案安裝 Node.js 和 Express.js 的型別定義。這將確保 Request、Response 和 NextFunction 型別能被識別並自動匯入。
要安裝 Node.js 的型別定義:
npm install --save-dev @types/node
要安裝 Express.js 的型別定義:
npm install --save-dev @types/express
就這樣!希望那有幫助。
