如何合并TypeScript泛型参数以减少代码冗余?
简化Axios请求的泛型参数写法
问题背景
现有代码:
const response = await axios.get<any, AxiosResponse<any, any>, any>('login');
希望改写为:
const response = await axios.get<CombinedGenerics>('login');
以此减少样板代码,但目前找不到解构类型参数的方法,查阅实例化表达式相关内容也不符合需求,寻求解决方案。
解决方案
1. 封装请求函数,通过单个泛型传递所有类型参数
创建封装函数,将多个泛型参数整合到一个自定义类型中,调用时只需传入这个整合后的类型:
// 定义整合后的泛型结构 type CombinedGenerics = { Data: any; // 对应axios.get的第一个泛型参数T Response: AxiosResponse<any, any>; // 对应第二个泛型参数R Request: any; // 对应第三个泛型参数D }; // 封装axios.get请求 async function get<T extends CombinedGenerics>(url: string) { return axios.get<T['Data'], T['Response'], T['Request']>(url); } // 使用示例 const response = await get<CombinedGenerics>('login');
如果需要自定义具体类型,只需修改CombinedGenerics的属性类型:
type LoginGenerics = { Data: LoginRequestData; Response: AxiosResponse<LoginResponseData, any>; Request: undefined; }; const loginResponse = await get<LoginGenerics>('login');
2. 定义类型别名映射Axios泛型参数
不封装函数的话,可直接创建类型别名,将单个泛型拆解为axios.get所需的多个参数:
// 预设常用的组合类型 type DefaultGetRequest = typeof axios.get<any, AxiosResponse<any, any>, any>; // 或创建可复用的泛型映射 type MapCombinedGenerics<T> = T extends { data: infer D; response: infer R; request: infer Re; } ? typeof axios.get<D, R, Re> : never; // 使用时指定整合后的类型 type LoginGet = MapCombinedGenerics<{ data: LoginRequestData; response: AxiosResponse<LoginResponseData>; request: undefined; }>;
3. 扩展Axios类型,设置泛型默认值
如果大部分场景用默认any类型,可扩展Axios类型定义,给泛型参数加默认值,减少手动传入次数:
declare module 'axios' { interface AxiosStatic { // 给三个泛型参数设置默认值,匹配原代码的any组合 get<T = any, R = AxiosResponse<T, any>, D = any>(url: string): Promise<R>; } } // 使用时无需传入泛型即可匹配原代码行为 const response = await axios.get('login'); // 需要自定义类型时,只需传入需要修改的参数(支持部分传参) const customResponse = await axios.get<LoginResponseData>('login');
内容的提问来源于stack exchange,提问作者Gochi Siyan
相关产品推荐
相关产品推荐

