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

TypeScript路由函数Middleware类型校验异常问题求助

自定义路由函数的TypeScript类型校验异常

问题描述

  • 自定义route函数中,middlewares参数始终触发类型错误,但直接使用ValidateMiddlewares类型标注变量时(如代码第72、75行)可正常校验
  • 调用route函数时(第98、107行)会报错,但错误提示标记整个middlewares数组,而非具体存在问题的中间件(例如AnalyticMiddleware)

相关代码

abstract class BaseMiddleware<
  Input extends Record<string, any>,
  Output extends Record<string, any>,
> {
  abstract index(data: Input): Output
}

abstract class BaseController<Input extends Record<string, any>> {
  abstract index(data: Input): void
}

class AuthMiddleware extends BaseMiddleware<{}, { userID: number }> {
  index(data: {}) {
    return {
      userID: 1,
    }
  }
}

class UserPopulateMiddleware extends BaseMiddleware<{ userID: number }, { username: string }> {
  index(data: { userID: number }) {
    return {
      username: `getUsernameFromUserID(${data.userID})`,
    }
  }
}

class AnalyticMiddleware extends BaseMiddleware<{ userID: number; username: string }, {}> {
  index(data: { userID: number; username: string }) {
    return {}
  }
}

class AuthorizedController extends BaseController<{ userID: number }> {
  index(data: { userID: number }) {}
}

class UserPopulatedController extends BaseController<{ userID: number; username: string }> {
  index(data: { userID: number; username: string }) {}
}

class Controller extends BaseController<{}> {
  index(data: {}) {}
}

type MiddlewareArray = BaseMiddleware<any, any>[]

type ValidateMiddlewares<
  T extends MiddlewareArray,
  V extends MiddlewareArray = T,
  Input extends Record<string, any> = Record<string, never>,
  Results extends any[] = [],
> = V extends [BaseMiddleware<Input, infer Output>, ...infer Tail extends MiddlewareArray]
  ? ValidateMiddlewares<T, Tail, Input & Output, [...Results, V[0]]>
  : V extends [BaseMiddleware<any, infer Output>, ...infer Tail extends MiddlewareArray]
  ? ValidateMiddlewares<T, Tail, Input, [...Results, BaseMiddleware<Input, Output>]>
  : Results

type MergeMiddlewaresOutput<
  T extends MiddlewareArray,
  Input extends Record<string, any> = {},
> = T extends [BaseMiddleware<any, infer Output>, ...infer Tail extends MiddlewareArray]
  ? MergeMiddlewaresOutput<Tail, Output & Input>
  : Input

type R1 = ValidateMiddlewares<
  [BaseMiddleware<{}, { token: string }>, BaseMiddleware<{ a: string }, { userID: number }>]
>
type R2 = ValidateMiddlewares<
  [BaseMiddleware<{}, { userID: number }>, BaseMiddleware<{ userID: number }, { username: string }>]
>
type R3 = ValidateMiddlewares<[AuthMiddleware, UserPopulateMiddleware]>
type R4 = ValidateMiddlewares<[UserPopulateMiddleware]>
type R5 = ValidateMiddlewares<[AuthMiddleware, AnalyticMiddleware]>

// 此处校验正常,仅AnalyticMiddleware会被标记错误——它需要userID和username输入,但AuthMiddleware只输出userID
const R5: ValidateMiddlewares<[AuthMiddleware, AnalyticMiddleware]> = [
  new AuthMiddleware(),
  new AnalyticMiddleware(),
]

// 此处校验正常
const R6: ValidateMiddlewares<[AuthMiddleware, UserPopulateMiddleware, AnalyticMiddleware]> = [
  new AuthMiddleware(),
  new UserPopulateMiddleware(),
  new AnalyticMiddleware(),
]

type ValidateController<
  Controller extends BaseController<{}>,
  Middlewares extends MiddlewareArray | [],
> = Controller extends BaseController<infer Data>
  ? MergeMiddlewaresOutput<Middlewares> extends Data
    ? Controller
    : never
  : never

type C1 = ValidateController<
  BaseController<{ userID: number }>,
  [BaseMiddleware<{}, { userID: number; username: string }>]
>

// 问题函数
const route = <Middlewares extends MiddlewareArray, Controller extends BaseController<any>>(
  path: string,
  middlewares: ValidateMiddlewares<Middlewares>,
  controller: ValidateController<Controller, Middlewares>,
) => {
  // 路由实现
}

route('test', [new AuthMiddleware(), new UserPopulateMiddleware()], new UserPopulatedController()) // 应该通过校验
route('test', [], new Controller()) // 通过校验
route('test', [], new UserPopulatedController()) // 错误
route('test', [new AuthMiddleware()], new UserPopulatedController()) // 错误
route('test', [new UserPopulateMiddleware()], new AuthorizedController()) // 错误
route('test', [new UserPopulateMiddleware()], new AuthorizedController()) // 错误
route('test', [], new AuthorizedController()) // 错误

// 此处报错符合预期,但错误提示标记整个数组而非AnalyticMiddleware
route('test', [new AuthMiddleware(), new AnalyticMiddleware()], new AuthorizedController()) // 错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:20:54