Skip to content

axios

在设置响应拦截器后,接口返回值怎么做类型声明?

axios 的拦截器,可以更改返回值,一般来说返回值是 AxiosResponse 类型的。

但是拦截器普遍的做法是,直接返回 data。对 AxiosResponse 解包,减少一层的 data。

这样的话,接口返回值也需要同步地做出更改。以下有 2 种方案来实现:

强制类型转换方案

该仓库为例:

响应拦截器解包 data
txt
client.addResponseInterceptor<HttpResponse>((response) => {
	const { data: responseData, status } = response;
	const { code, data, message: msg } = responseData;
	if (status >= 200 && status < 400 && code === 0) {
		return data;
	}
	throw new Error(msg);
});

用强制类型转换来完成返回值的设置:

封装通用请求函数并强制类型转换
txt
class RequestClient {
	/**
	 * 通用的请求方法
	 */
	public async request<T>(url: string, config: AxiosRequestConfig): Promise<T> {
		try {
			const response: AxiosResponse<T> = await this.instance({
				url,
				...config,
			});
			return response as T;
		} catch (error: any) {
			throw error.response ? error.response.data : error;
		}
	}
}

该方案要求我们封装通用请求函数,并强制类型转换。接口请求函数整体来说就变得比较复杂了。

泛型函数传参方案

该仓库为例:

响应拦截器解包 data
txt
// 响应拦截器
service.interceptors.response.use(
	(response: AxiosResponse) => {
		// 检查配置的响应类型是否为二进制类型('blob' 或 'arraybuffer'), 如果是,直接返回响应对象
		if (response.config.responseType === "blob" || response.config.responseType === "arraybuffer") {
			return response;
		}

		const { code, data, msg } = response.data;
		if (code === ResultEnum.SUCCESS) {
			return data;
		}

		ElMessage.error(msg || "系统出错");
		return Promise.reject(new Error(msg || "Error"));
	},
	(error: any) => {
		// 异常处理
		if (error.response.data) {
			const { code, msg } = error.response.data;
			if (code === ResultEnum.TOKEN_INVALID) {
				ElNotification({
					title: "提示",
					message: "您的会话已过期,请重新登录",
					type: "info",
				});
				useUserStoreHook()
					.resetToken()
					.then(() => {
						location.reload();
					});
			} else {
				ElMessage.error(msg || "系统出错");
			}
		}
		return Promise.reject(error.message);
	},
);

在使用的时候,针对第一个泛型参数,直接填值为 any。重点为第二个泛型参数的填写,直接填写我们期望的返回值即可:

泛型函数传参
txt
function getPage(queryParams: DictPageQuery) {
	return request<any, PageResult<DictPageVO[]>>({
		url: `${DICT_BASE_URL}/page`,
		method: "get",
		params: queryParams,
	});
}

该方案要求我们写较多的 any,可能会带来误导。

贡献者

The avatar of contributor named as ruan-cat ruan-cat

页面历史

布局切换

调整 VitePress 的布局样式,以适配不同的阅读习惯和屏幕环境。

全部展开
使侧边栏和内容区域占据整个屏幕的全部宽度。
全部展开,但侧边栏宽度可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
全部展开,且侧边栏和内容区域宽度均可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
原始宽度
原始的 VitePress 默认布局宽度

页面最大宽度

调整 VitePress 布局中页面的宽度,以适配不同的阅读习惯和屏幕环境。

调整页面最大宽度
一个可调整的滑块,用于选择和自定义页面最大宽度。

内容最大宽度

调整 VitePress 布局中内容区域的宽度,以适配不同的阅读习惯和屏幕环境。

调整内容最大宽度
一个可调整的滑块,用于选择和自定义内容最大宽度。

聚光灯

支持在正文中高亮当前鼠标悬停的行和元素,以优化阅读和专注困难的用户的阅读体验。

ON开启
开启聚光灯。
OFF关闭
关闭聚光灯。