如何为Axios请求正确添加类型注解?含无参端点场景
问题:将openapi-typescript生成的类型应用到Vue Axios请求中
我使用openapi-typescript为API生成了类型注解,希望在Vue项目的Axios请求中复用这些类型,但当前代码的类型提示不完善(比如IDE hover params时无法识别其类型),AxiosResponse的泛型配置也没达到预期效果。
现有代码示例
type FactRepeater = components['schemas']['FactRepeater']; type FactRepeaterResponse = paths['/api/v1/repeaters/fact-repeater/']['get']['responses']['200']['content']['application/json']; type FactRepeaterRequest = paths['/api/v1/repeaters/fact-repeater/']['get']['parameters']['query']; const repeaters: Ref<Array<FactRepeater>> = ref([]); async function requestRepeaters( limit: number, offset: number, ordering: string | null = null, ): Promise<void> { try { const response: AxiosResponse<FactRepeaterResponse, FactRepeaterRequest> = await api.get('/api/v1/repeaters/fact-repeater/', { params: { limit, offset, ordering }, }); repeaters.value = response.data.results!; pagination.value.rowsNumber = response.data.count!; } catch (error) { console.error(error); } }
关联Schema片段
// ... // components["schemas"] FactRepeater: { id: number; // ... }; // ... PaginatedFactRepeaterList: { count?: number; next?: string | null; previous?: string | null; results?: components["schemas"]["FactRepeater"][]; }; // ... // paths['/api/v1/repeaters/fact-repeater/']['get'] responses: { 200: { content: { "application/json": components["schemas"]["PaginatedFactRepeaterList"]; }; }; }; parameters: { query?: { ordering?: string; limit?: number; offset?: number; // ... }; }; // ...
解决方案
一、修复请求参数类型提示问题
Axios的get方法泛型参数中,第二个泛型不是用于标注URL查询参数类型(它默认对应POST请求的body数据类型)。要让IDE识别params的类型,需要直接给请求配置里的params字段显式指定类型:
修改后的代码
type FactRepeater = components['schemas']['FactRepeater']; type FactRepeaterResponse = paths['/api/v1/repeaters/fact-repeater/']['get']['responses']['200']['content']['application/json']; // 明确提取查询参数类型 type FactRepeaterQueryParams = paths['/api/v1/repeaters/fact-repeater/']['get']['parameters']['query']; const repeaters: Ref<Array<FactRepeater>> = ref([]); async function requestRepeaters( limit: number, offset: number, ordering: string | null = null, ): Promise<void> { try { // 给params指定类型,同时AxiosResponse只需要传入响应数据类型 const response = await api.get<FactRepeaterResponse>('/api/v1/repeaters/fact-repeater/', { params: { limit, offset, ordering } as FactRepeaterQueryParams, }); repeaters.value = response.data.results!; pagination.value.rowsNumber = response.data.count!; } catch (error) { console.error(error); } }
更严谨的写法(对齐函数参数与API参数类型)
直接用生成的查询参数类型定义函数入参,从源头确保类型一致:
async function requestRepeaters(params: FactRepeaterQueryParams): Promise<void> { try { const response = await api.get<FactRepeaterResponse>('/api/v1/repeaters/fact-repeater/', { params }); repeaters.value = response.data.results!; pagination.value.rowsNumber = response.data.count!; } catch (error) { console.error(error); } } // 调用时IDE会自动提示合法参数 requestRepeaters({ limit: 10, offset: 0, ordering: 'id' });
二、端点无请求参数时的处理
如果API端点没有可配置的请求参数:
- 提取的请求参数类型默认是
undefined,可以将其转为never或Record<string, never>,明确表示无参数可传 - 请求时不需要传入
params字段,若误传多余参数,IDE会直接抛出类型错误
示例代码
// 无参数端点的类型提取 type NoParamsResponse = paths['/api/v1/xxx/']['get']['responses']['200']['content']['application/json']; // 处理无参数的情况,将类型转为never type NoParamsQuery = paths['/api/v1/xxx/']['get']['parameters']['query'] extends undefined ? never : paths['/api/v1/xxx/']['get']['parameters']['query']; async function requestNoParams(): Promise<void> { try { const response = await api.get<NoParamsResponse>('/api/v1/xxx/'); // 处理响应逻辑 } catch (error) { console.error(error); } } // 误传参数会触发类型错误 await api.get('/api/v1/xxx/', { params: { foo: 'bar' } }); // IDE报错:参数不合法
内容的提问来源于stack exchange,提问作者Rui Oliveira
相关产品推荐
相关产品推荐

