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

TypeScript:如何按HTTP方法过滤接口生成对应子类型

问题

现有如下 TypeScript 接口定义:

interface paths {
  "/api/user/{id}": {
    get: operations["getUserGET"];
  };
  "/api/user/add": {
    put: operations["addUsingPUT"];
  };
  // 其他接口路径...
}

如何通过指定 HTTP 方法(如 get、put、post 等)过滤这个接口,生成只包含匹配该方法的子类型?期望效果如下:

type getPaths = AwesomeFilter<paths, 'get'>

/* 等价于: */
interface getPaths {
  "/api/user/{id}": {
    get: operations["getUserGET"];
  };
  // 仅保留包含 get 方法的接口路径
}
解决方案

利用 TypeScript 的映射类型和条件类型,可以实现这个AwesomeFilter工具类型,精准过滤出包含指定 HTTP 方法的接口路径:

type AwesomeFilter<Paths extends Record<string, any>, Method extends string> = {
  [K in keyof Paths as Paths[K] extends Record<Method, unknown> ? K : never]: {
    [M in Method]: Paths[K][M]
  }
}

代码说明

  1. 路径过滤:外层的[K in keyof Paths as ...]遍历原接口的所有路径键,通过条件判断过滤——只有当路径对应的对象包含目标Method时,才保留该路径键,否则直接剔除。
  2. 方法提取:对保留的路径,只提取目标 HTTP 方法对应的类型,确保最终生成的类型只包含需要的方法,不会混入其他无关方法。

使用示例

假设我们有完整的接口定义:

interface operations {
  getUserGET: { status: number; data: { id: string; name: string } },
  addUsingPUT: { status: number; message: string },
  deleteUserDELETE: { status: number }
}

interface paths {
  "/api/user/{id}": {
    get: operations["getUserGET"];
    delete: operations["deleteUserDELETE"];
  };
  "/api/user/add": {
    put: operations["addUsingPUT"];
  };
  "/api/user/list": {
    get: { status: number; data: Array<{ id: string; name: string }> };
  };
}

// 筛选所有含 GET 方法的路径
type GetPaths = AwesomeFilter<paths, 'get'>
/* 最终生成的类型等价于:
interface GetPaths {
  "/api/user/{id}": { get: operations["getUserGET"] };
  "/api/user/list": { get: { status: number; data: Array<{ id: string; name: string }> } };
}
*/

// 筛选所有含 PUT 方法的路径
type PutPaths = AwesomeFilter<paths, 'put'>
/* 最终生成的类型等价于:
interface PutPaths {
  "/api/user/add": { put: operations["addUsingPUT"] };
}
*/

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:20:19