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

TypeScript中如何让泛型参数无需按固定顺序传递?

实现方案

可以通过「收拢分散泛型参数为单个配置对象类型」的方式,实现类似命名传参的效果,无需按顺序传递泛型,仅指定需要自定义的字段即可,其余字段自动使用预设默认值。

第一步:定义统一的泛型配置接口

首先把所有泛型参数收拢到一个接口里,同时设置通用默认值:

interface MiddlewareOptions {
  Store: never
  Args: unknown
  Response: unknown
  // 后续新增泛型参数直接在这里加即可,不会影响原有使用逻辑
}

第二步:写泛型合并工具(简化代码)

写一个通用工具类型,自动合并用户传入的自定义配置和默认配置:

// 作用:用户传了的字段用用户的,没传的用默认值
type MergeDefault<T, Default> = T & Omit<Default, keyof T>

第三步:改造原Middleware类型

把原来的多泛型参数改为单泛型接收配置对象:

export type Middleware<T extends Partial<MiddlewareOptions> = {}> = (
  context: {
    endpoint: string
    args: MergeDefault<T, MiddlewareOptions>['Args']
    locals: {
      store?: MergeDefault<T, MiddlewareOptions>['Store']
      [key: string]: unknown
    }
  }
) => Promise<MergeDefault<T, MiddlewareOptions>['Response'] | void> | MergeDefault<T, MiddlewareOptions>['Response'] | void

使用示例

无需记忆泛型顺序,按需指定需要自定义的字段即可:

  • 仅自定义Args类型,其余用默认值:
// 等价于原写法 Middleware<never, { id: number }, unknown>,无需手动补前置的never
type GetUserMiddleware = Middleware<{ Args: { id: number } }>
  • 仅自定义Response和Store,跳过Args:
// 等价于原写法 Middleware<{ uid: string }, unknown, { code: number; data: any }>
type CommonMiddleware = Middleware<{ 
  Response: { code: number; data: any }, 
  Store: { uid: string } 
}>

方案优势

  • 完全不依赖泛型传参顺序,不需要手动填写不需要的前置泛型值
  • 后续新增泛型配置仅需在MiddlewareOptions中新增字段并设置默认值,旧的使用代码无需任何改动,兼容性极强
  • 字段名语义化,不需要记忆泛型位置,开发体验更好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:24:09