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

TypeScript实现支持类型推导的Express中间件管道函数

实现支持任意数量中间件的Express Request属性增强工具

你需要构建一个工具函数,让Express中间件可以逐步为Request对象添加属性,且后续中间件能在保留类型提示的前提下访问这些属性。当前的实现仅支持固定数量的中间件,需要手动扩展类型参数,不够灵活。以下是优化后的解决方案,支持任意数量的中间件参数,并保持完整的类型推导。

需求示例

期望的使用方式如下,后续中间件能直接访问前面步骤添加的属性:

app.post(
  '/some/endpoint',
  pipeMiddleware(
    (req, res) => {
      // 执行异步操作
      return { entity: { /* ... */ } };
    },
    (req, res) => {
      // 此处可直接访问req.entity
      return { otherEntity: { /* ... */ } };
    },
    (req, res) => {
      // 此处可同时访问req.entity和req.otherEntity
      handler(req.entity, req.otherEntity, req.body, res);
      return {};
    }
  )
);

优化后的实现

通过递归类型推导和动态中间件执行,实现支持任意数量步骤的工具函数:

import { Request, Response, NextFunction } from 'express';

// 定义单个中间件步骤的类型:接收当前Request,返回要添加的属性对象
type MiddlewareStep<Req extends Request, AddedProps> = (
  req: Req,
  res: Response
) => Promise<AddedProps>;

// 递归类型,用于累积中间件链的Request属性类型
type MiddlewareChain<Req extends Request, AccumulatedProps = {}> = {
  // 终止调用:生成最终的Express中间件
  (): (req: Req, res: Response, next?: NextFunction) => Promise<Req & AccumulatedProps>;
  // 添加一个中间件步骤,累积属性类型
  <NextProps>(
    step: MiddlewareStep<Req & AccumulatedProps, NextProps>
  ): MiddlewareChain<Req, AccumulatedProps & NextProps>;
};

function pipeMiddleware<Req extends Request = Request>(
  ...steps: MiddlewareStep<any, any>[]
): (req: Req, res: Response, next?: NextFunction) => Promise<Req & Record<string, any>>;
function pipeMiddleware<Req extends Request = Request>(): MiddlewareChain<Req>;
function pipeMiddleware<Req extends Request = Request>(
  ...args: any[]
): any {
  const steps: MiddlewareStep<any, any>[] = [];

  // 链式调用模式:初始无参数,逐步添加中间件
  if (args.length === 0) {
    const chain: any = (step?: MiddlewareStep<any, any>) => {
      if (!step) {
        // 执行所有中间件步骤
        return async (req: Req, res: Response, next?: NextFunction) => {
          let currentReq = req as Req & Record<string, any>;
          try {
            for (const stepFn of steps) {
              const addedProps = await stepFn(currentReq, res);
              Object.assign(currentReq, addedProps);
            }
            next?.();
            return currentReq;
          } catch (err) {
            next?.(err);
            throw err;
          }
        };
      }
      steps.push(step);
      return chain;
    };
    return chain;
  }

  // 直接传入多个中间件的模式
  steps.push(...args);
  return async (req: Req, res: Response, next?: NextFunction) => {
    let currentReq = req as Req & Record<string, any>;
    try {
      for (const stepFn of steps) {
        const addedProps = await stepFn(currentReq, res);
        Object.assign(currentReq, addedProps);
      }
      next?.();
      return currentReq;
    } catch (err) {
      next?.(err);
      throw err;
    }
  };
}

核心特性

  • 任意数量中间件:无需手动扩展类型参数,支持传入任意多个中间件步骤
  • 完整类型推导:每个中间件的req参数会自动包含前面所有步骤添加的属性,TypeScript能正确提供类型提示和检查
  • 两种调用方式:支持直接传入多个中间件,或通过链式调用逐步添加
  • 错误处理兼容:兼容Express的NextFunction,错误会传递给后续错误处理中间件

使用示例

直接传入多个中间件

app.post(
  '/some/endpoint',
  pipeMiddleware(
    async (req, res) => {
      const entity = await fetchEntity(req.params.id);
      return { entity };
    },
    async (req, res) => {
      // 此处req.entity类型已被正确推导
      const otherEntity = await fetchRelatedEntity(req.entity.id);
      return { otherEntity };
    },
    async (req, res) => {
      // 此处可访问req.entity和req.otherEntity
      await saveData(req.entity, req.otherEntity);
      res.status(200).json({ success: true });
      return {};
    }
  )
);

链式调用添加中间件

app.get(
  '/user/profile',
  pipeMiddleware()
    .addStep(async (req, res) => {
      const user = await getUser(req.headers.authorization);
      return { user };
    })
    .addStep(async (req, res) => {
      const profile = await getUserProfile(req.user.id);
      return { profile };
    })
    .addStep(async (req, res) => {
      res.status(200).json({ user: req.user, profile: req.profile });
      return {};
    })() // 最后调用()生成Express中间件
);

内容的提问来源于stack exchange,提问作者mikey-mike

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 19:50:37