You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:54:15