如何为Express.js错误处理中间件的RequestHandler声明自定义参数类型?
Express错误处理中间件的TypeScript类型修复方案
问题场景
在Express应用中编写错误处理中间件时,遇到类型声明错误:第一个普通中间件调用next(error)传递错误对象,第二个错误处理中间件因使用RequestHandler类型导致类型不匹配。原代码如下:
export const errorMiddleware = (app: Application): void => { // 路由不存在时的处理 app.use(((req, res, next): void => { const error: any = new Error("Route not found"); error.status = 404; next(error); logger.error(`${error.status} ${error.message}`); }) as RequestHandler); // 捕获抛出的错误 app.use(((error, req, res, next): void => { logger.error(`${error.status} ${error.message}`); res.status(error.status || 500).json({ error: { message: error.message, }, status: error.status || 500, }); }) as RequestHandler); };
问题原因
Express的TypeScript类型定义中,RequestHandler是普通中间件的类型签名(参数为req, res, next),而错误处理中间件的参数签名为(error, req, res, next),需要使用专门的**ErrorRequestHandler**类型来匹配。另外,原代码用any定义错误对象不够严谨,缺乏类型安全性。
修复方案
1. 使用正确的类型签名
错误处理中间件替换为ErrorRequestHandler类型,普通中间件保持RequestHandler类型。
2. 自定义错误类型
扩展原生Error类型,添加status属性,避免使用any。
修复后的完整代码:
import { Application, RequestHandler, ErrorRequestHandler } from 'express'; // 自定义错误类型,扩展Error添加可选status属性 interface CustomError extends Error { status?: number; } export const errorMiddleware = (app: Application): void => { // 路由不存在的普通中间件,使用RequestHandler类型 app.use((req, res, next): void => { const error: CustomError = new Error("Route not found"); error.status = 404; logger.error(`${error.status} ${error.message}`); next(error); // 传递错误到下一个错误处理中间件 } as RequestHandler); // 错误处理中间件,使用ErrorRequestHandler类型 app.use((error: CustomError, req, res, next): void => { logger.error(`${error.status || 500} ${error.message}`); res.status(error.status || 500).json({ error: { message: error.message, }, status: error.status || 500, }); } as ErrorRequestHandler); };
关键说明
ErrorRequestHandler是Express为错误处理中间件提供的专属类型,完美匹配(error, req, res, next)的参数顺序。- 自定义
CustomError接口可以让TypeScript对错误对象的status属性进行类型检查,避免隐式类型转换的风险。 - 调整日志记录顺序:先记录日志再调用
next(error),确保错误信息被正确捕获。
内容的提问来源于stack exchange,提问作者Mehdi Faraji
相关产品推荐
相关产品推荐

