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

解决Express res.end()的TypeScript错误:void无法赋值给Response类型

问题:重写Express.js的res.end()方法时出现TypeScript类型错误

我希望通过扩展Express.js的res.end()方法实现自定义日志功能,编写了如下代码:

export async function inOutLogger(req: express.Request, res: express.Response, next: express.NextFunction): Promise<any> {
  
...
  // 假设此处已保存原res.end的引用到oldEnd
  res.end = (...restArgs) => {
    if (restArgs[0]) {
      chunks.push(Buffer.from(restArgs[0]));
    }

    oldEnd.apply(res, restArgs);
    logFn();
  };
...

export default logger;

但重写时遇到以下TypeScript错误:

Type '(...restArgs: any[]) => void' is not assignable to type '{ (cb?: () => void): Response<any, Record<string, any>>; (chunk: any, cb?: () => void): Response<any, Record<string, any>>; (chunk: any, encoding: string, cb?: () => void): Response<...>; }'.ts(2322)
Type '(...restArgs: any[]) => void' is not assignable to type '{ (cb?: () => void): Response<any, Record<string, any>>; (chunk: any, cb?: () => void): Response<any, Record<string, any>>; (chunk: any, encoding: string, cb?: () => void): Response<...>; }'.
  Type 'void' is not assignable to type 'Response<any, Record<string, any>>'.ts(2322)

我知道需要返回某个值,但不清楚正确的返回类型,请问该如何解决?


解决方法

错误原因

Express的res.end()方法包含三种重载签名,所有签名都要求返回Response对象。你重写的函数没有返回值(默认返回void),同时参数restArgs的类型为any[],不符合原方法的类型定义,因此触发了TypeScript类型检查错误。

修正步骤

  1. 先保存原始res.end方法的引用并指定正确类型
  2. 重写的函数需要:
    • 匹配原res.end的参数类型
    • 返回原始res.end调用后的结果(即Response对象)

修正后的代码

import express from 'express';

export async function inOutLogger(req: express.Request, res: express.Response, next: express.NextFunction): Promise<any> {
  // 保存原始res.end方法,自动推导类型
  const oldEnd = res.end;
  const chunks: Buffer[] = [];

  // 重写res.end,严格匹配原方法的参数类型
  res.end = (...restArgs: Parameters<typeof res.end>) => {
    // 收集响应chunk
    if (restArgs[0]) {
      chunks.push(Buffer.from(restArgs[0]));
    }

    // 调用原始end方法,获取返回的Response对象
    const response = oldEnd.apply(res, restArgs);
    // 执行自定义日志逻辑
    logFn();
    // 返回Response对象,符合类型要求
    return response;
  };

  next();
}

// 自定义日志函数示例
function logFn() {
  // 此处编写你的日志逻辑
}

export default inOutLogger;

关键说明

  • 使用Parameters<typeof res.end>自动推导原res.end的参数类型,无需手动编写复杂的重载签名
  • 原始res.end方法会返回当前的Response对象(即this),因此必须返回该结果以满足类型要求
  • 若logFn是异步函数,建议用void logFn()调用以避免类型警告,同时需自行处理异步日志的错误捕获

内容的提问来源于stack exchange,提问作者f.bele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:40:34