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

Express路由调用返回中间件的函数时TypeScript类型报错求解决

自定义Express中间件validateBody的TypeScript类型兼容问题解决

问题场景

我正在实现一个用于API请求体验证的自定义函数validateBody,代码如下:

export function validateBody(schema: string): (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void {
    return function (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction): void | ExpressResponse {
        // 验证逻辑
        next();
    }
}

在Express路由中以返回中间件的方式调用:

router.route('/api/users/currentuser').get(validateBody('signIn'), (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => {
    // 路由处理逻辑
});

此时出现TypeScript lint错误:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '(req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void' is not assignable to parameter of type 'RequestHandlerParams<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
      Type '(req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void' is not assignable to type 'RequestHandler<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
        Types of parameters 'req' and 'req' are incompatible.
          Property 'value' is missing in type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>' but required in type 'ExpressRequest'.ts(2769)
types.ts(4, 5): 'value' is declared here.
index.d.ts(222, 5): The last overload is declared here.

直接使用RequestHandlerParams类型约束validateBody返回值时,函数定义又会报错。使用JavaScript开发时无此问题,需要可行的解决方案或变通方法。

解决方案

1. 修正自定义请求类型的继承关系

你的ExpressRequest是自定义类型,必须确保它继承自Express官方的Request类型,才能与路由中间件的类型系统兼容:

// types.ts
import { Request } from 'express';

export interface ExpressRequest extends Request {
  value?: any; // 根据实际业务定义属性的具体类型
}

2. 用Express原生RequestHandler约束返回值

直接使用Express提供的RequestHandler类型来定义validateBody的返回值,避免手动声明参数类型,让类型系统自动匹配:

import { RequestHandler, Response, NextFunction } from 'express';
import { ExpressRequest } from './types';

export function validateBody(schema: string): RequestHandler {
    return function (req: ExpressRequest, res: Response, next: NextFunction): void | Response {
        // 验证逻辑
        next();
    }
}

由于ExpressRequest继承了原生Request,这里的参数类型会被自动识别为合法的中间件参数类型。

3. 临时类型断言(变通方案)

如果暂时无法修改类型定义,可以在路由调用时使用类型断言跳过检查:

import { RequestHandler } from 'express';

router.route('/api/users/currentuser').get(
  validateBody('signIn') as RequestHandler,
  (req: ExpressRequest, res: Response, next: NextFunction) => {
    // 路由处理逻辑
  }
);

注意:此方法会绕过TypeScript的类型校验,仅作为临时应急方案,不推荐长期使用。

内容的提问来源于stack exchange,提问作者DrusePstrago

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:31