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

使用openapi-typescript时,函数为何无法正确推导类型?

解决openapi-typescript生成类型后get函数返回值类型推导失败的问题

我通过openapi-typescript从Swagger服务生成了完整的类型定义,接着创建了仅包含GET方法路径的GetUrls类型。写好get函数后,URL的自动补全正常工作,但返回值类型无法正确推导;只有手动指定URL索引时,类型推导才会正常生效。

现有代码:

import { paths } from '../types/swagger.js'

// 省略FilterPaths的实现代码
type GetPaths = FilterPaths<paths, 'get'>
type GetUrls = keyof GetPaths & string

// 省略Params类型定义
const get = async (url: GetUrls, params: Params) => {
    let path = ''
    for (let param in params) {
        path = url.replace('{' + param + '}', params[param])
    }

    type Schema = GetPaths[typeof url]['get']['responses']['200']['content']['*/*']

    return (await axios.get<Schema>(path)).data
}

get('/api/user/{id}', { id: '123' }).then(data => console.log(data))

手动指定索引时类型推导正常:

type Schema = GetPaths['/api/user/{id}']['get']['responses']['200']['content']['*/*']

解决方案

问题出在typeof url的类型是GetUrls联合类型,导致Schema变成了所有GET接口返回类型的集合,而非当前调用时传入的具体URL对应的类型。要解决这个问题,需要把get函数改成泛型函数,让TypeScript在调用时捕获具体的URL类型:

修改后的代码

import { paths } from '../types/swagger.js'

// 实现FilterPaths工具类型(过滤出指定请求方法的路径)
type FilterPaths<T, Method extends string> = {
  [K in keyof T]: Method extends keyof T[K] ? T[K] : never
}

type GetPaths = FilterPaths<paths, 'get'>
type GetUrls = keyof GetPaths & string

// 自动推导对应URL的路径参数类型
type PathParams<Url extends GetUrls> = 
  GetPaths[Url]['get']['parameters']['path'] extends Record<string, infer ParamDef>
    ? { [K in keyof ParamDef]: ParamDef[K]['schema']['type'] }
    : {}

const get = async <Url extends GetUrls>(url: Url, params: PathParams<Url>) => {
  let path = url
  // 替换路径参数
  for (const param in params) {
    path = path.replace(`{${param}}`, params[param])
  }

  // 精准获取当前URL对应的返回类型
  type Schema = GetPaths[Url]['get']['responses']['200']['content']['*/*']['schema']
  
  return (await axios.get<Schema>(path)).data
}

// 调用示例:此时data的类型会自动推导为/api/user/{id}接口的200返回类型
get('/api/user/{id}', { id: '123' }).then(data => {
  console.log(data)
})

关键说明

  1. 泛型约束URL类型:通过<Url extends GetUrls>将url参数的类型锁定为调用时传入的具体路径,而非联合类型,这样TypeScript能精准定位到对应的接口定义。
  2. 自动推导路径参数:新增的PathParams泛型类型会根据传入的URL自动生成所需的参数结构,既保证类型安全,又不用手动定义每个接口的参数类型。
  3. 精准获取返回类型:现在Schema基于泛型Url获取对应的返回类型,不再是所有类型的联合,解决了返回值类型推导失败的问题。

注意事项

  • 若你的openapi-typescript生成的类型结构中,媒体类型不是*/*(比如常见的application/json),需要调整content后的键名。
  • 如果部分接口没有200响应,可添加条件类型处理这种情况,避免类型报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:05:17