在对axios拦截器封装时,报一个关于AxiosHeaders的类型继承错误,以下给出解决方案。
1、axios原始封装代码
type.ts (对interceptors封装的代码)
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
type AxiosRequestConfig,
type InternalAxiosRequestConfig,
type AxiosResponse,
} from "axios";
interface HInterceptors<T = AxiosResponse> {
requestSuccessFn?: (
config: InternalAxiosRequestConfig
) => InternalAxiosRequestConfig;
requestFailureFn?: (err: any) => any;
responseSuccessFn?: (res: T) => T;
responseFailureFn?: (err: any) => any;
}
//针对AxiosRequestConfig配置进行扩展(在里面再次添加自定义interceptors拦截器)
export interface HRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: HInterceptors<T>;
}
request.ts主代码逻辑
import axios from "axios";
import type { AxiosInstance } from "axios";
import type { HRequestConfig } from "./type";
class Request {
instance: AxiosInstance;
constructor(config: HRequestConfig) {
this.instance = axios.create(config);
this.instance.interceptors.request.use(
(config) => {
return config;
},
(err) => {
return err;
}
);
this.instance.interceptors.response.use(
(res) => {
return res.data;
},
(err) => {
return err;
}
);
//针对特定的hyRequest的实例添加拦截器
this.instance.interceptors.request.use(
config.interceptors?.requestSuccessFn,
config.interceptors?.requestFailureFn
);
this.instance.interceptors.response.use(
config.interceptors?.responseSuccessFn,
config.interceptors?.responseFailureFn
);
}
//封装网络请求的方法
request<T = any>(config: HRequestConfig<T>) {
if (config.interceptors?.requestSuccessFn) {
config = config.interceptors.requestSuccessFn(config);
}
return new Promise<T>((resolve, reject) => {
this.instance
.request<any, T>(config)
.then((res) => {
//单次响应成功的拦截处理
if (config.interceptors?.responseSuccessFn) {
res = config.interceptors.responseSuccessFn(res);
}
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
get<T = any>(config: HRequestConfig<T>) {
return this.request({ ...config, method: "GET" });
}
post<T = any>(config: HRequestConfig<T>) {
return this.request({ ...config, method: "POST" });
}
delete<T = any>(config: HRequestConfig<T>) {
return this.request({ ...config, method: "DELETE" });
}
patch<T = any>(config: HRequestConfig<T>) {
return this.request({ ...config, method: "PATCH" });
}
}
export default Request;
2、错误提示
- 在request.ts自定义的拦截器部分报错
报错原因:
- 查看axios的源码可知request的泛型为InternalAxiosRequestConfig,而自定义的HRequestConfig继承是AxiosRequestConfig,对应的headers不同。好了接下来直接给出解决方法。
3、解决方法
- 步骤① 在type.ts中加上headers
...
export interface HRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: HInterceptors<T>;
headers?: AxiosRequestHeaders;
}
- 步骤② 在request.ts中发送请求时将config类型转为InternalAxiosRequestConfig即可完成
...
request<T = any>(config: HRequestConfig<T>) {
if (config.interceptors?.requestSuccessFn) {
config = config.interceptors.requestSuccessFn(
config as InternalAxiosRequestConfig
);
}
4、使用二次封装的axios发送请求
书写一个发送请求的index.ts
import HRequest from "./request";
const Request = new HRequest({
baseURL: "http://codercba.com:9002",
timeout: 10000,
interceptors: {
requestSuccessFn: (config) => {
return config;
},
},
});
export default Request;
在前端页面中掉用封装的Request发起请求
控制台打印成功