如何解决Axios自定义Hook中AxiosError的unknown类型错误?
解决Axios自定义Hook的TypeScript类型错误
错误原因
TypeScript 中 catch 块捕获的错误默认类型是 unknown,而你的 setError 状态接受的是 AxiosError | undefined,直接赋值会触发类型不兼容的报错。
最佳处理方案
1. 使用Axios内置类型守卫(推荐)
利用Axios提供的isAxiosError方法做类型判断,既能保证类型安全,又能处理非Axios抛出的错误:
catch (error) { if (axios.isAxiosError(error)) { setError(error); } else { // 可选:处理非Axios错误,比如转为自定义AxiosError或记录日志 setError(new AxiosError('请求发生非预期错误')); console.error('非Axios错误:', error); } }
这个方法是最严谨的,因为网络请求过程中可能抛出非Axios的错误(比如运行时异常),类型守卫能帮你精准区分。
2. 类型断言(仅限确定错误类型场景)
如果你能100%保证catch捕获的都是AxiosError,可以直接用类型断言跳过检查,但这种方式不够安全,不推荐在复杂场景使用:
catch (error) { setError(error as AxiosError); }
3. 优化Hook的泛型支持(可选)
为了让自定义Hook更通用,可以给AxiosResponse和AxiosError添加泛型参数,方便指定响应数据和错误数据的类型:
import { useEffect, useState } from 'react'; import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'; const useAxios = <ResponseData = unknown, ErrorData = unknown>(axiosParams: AxiosRequestConfig) => { const [response, setResponse] = useState<AxiosResponse<ResponseData>>(); const [error, setError] = useState<AxiosError<ErrorData>>(); const [loading, setLoading] = useState(false); axios.defaults.baseURL = import.meta.env.VITE_BASE_URL; useEffect(() => { (async (params: AxiosRequestConfig) => { setLoading(true); try { const response = await axios.request(params); setResponse(response); } catch (error) { if (axios.isAxiosError(error)) { setError(error); } else { setError(new AxiosError<ErrorData>('非Axios请求错误')); console.error('非Axios错误:', error); } } finally { setLoading(false); } })(axiosParams); }, [axiosParams]); // 注意:这里要把axiosParams加入依赖数组,否则参数变化时不会重新请求 return { response, error, loading }; }; export default useAxios;
另外注意:原代码中useEffect的依赖数组是空的,这意味着只有组件挂载时会执行一次请求。如果你的axiosParams可能变化,需要把它加入依赖数组,否则参数更新后不会触发新的请求。
内容的提问来源于stack exchange,提问作者Legion
相关产品推荐
相关产品推荐

