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

如何根据Handler参数类型自动推断compose返回的Middleware泛型参数?

TypeScript自动推断compose中间件返回类型的实现方案

你的核心需求是让compose返回的中间件函数,自动根据最终传入的handler返回值类型推断自身返回类型,无需显式指定泛型参数。这个需求完全可以实现,关键是把泛型推断的时机从调用compose时,延迟到调用返回的中间件函数时。

问题根源

原代码中compose<T>的泛型参数T在调用compose时就需要确定,但此时还未传入最终的handler,TypeScript只能将T推断为unknown,导致后续result.id报错。

解决方案

修改compose的定义,让它返回一个泛型中间件函数,而非提前绑定死T的中间件。具体代码如下:

export type Context = any;
export type Handler<T> = (ctx: Context) => Promise<T>;
export type Middleware<T> = (ctx: Context, handler: Handler<T>) => Promise<T>;

// 移除compose自身的泛型参数,返回一个泛型的Middleware函数
export function compose(...middlewares: Middleware<unknown>[]): <T>Middleware<T> {
  return async function compositeMiddleware<T>(
    ctx: Context, 
    handler: Handler<T>
  ): Promise<T> {
    // 中间件链式调用的示例实现
    const chain = middlewares.reduceRight((next, middleware) => {
      return () => middleware(ctx, next);
    }, handler);
    return chain(ctx);
  };
}

修正中间件定义

为避免隐式类型问题,建议明确指定中间件的泛型为unknown(你的中间件仅透传结果,不依赖特定类型):

const middleware1: Middleware<unknown> = async (ctx, next) => {
  console.log('Middleware 1 Before');
  const result = await next(ctx);
  console.log('Middleware 1 After');
  return result;
};

const middleware2: Middleware<unknown> = async (ctx: Context, next: Handler<unknown>) => {
  console.log('Middleware 2 Before');
  const result = await next(ctx);
  console.log('Middleware 2 After');
  return result;
};

使用效果

现在调用compose得到的compositeMiddleware是一个泛型函数,传入最终handler时,TypeScript会自动推断返回类型:

const compositeMiddleware = compose(middleware1, middleware2);

const result = await compositeMiddleware({}, async () => {
  return { id: 'mock-id' };
});

result.id; // 正确推断为string类型,无报错

原理说明

通过让compose返回<T>Middleware<T>,我们把泛型T的推断时机延迟到了调用compositeMiddleware的时候——此时TypeScript已能获取最终handler的返回值类型,自然可以自动推断出T,让result的类型完全匹配handler的返回类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:57:50