Typescript中使用 axios 发请求
简易封装请求
import { store } from "./../store/index";
import axios from "axios";
const request = axios.create({
baseURL: "http://toutiao.itheima.net/v1_0",
timeout: 5000,
});
// 请求拦截器
request.interceptors.request.use((config) => {
// 获取store中token
const { token } = store.getState();
// 添加token(需要非空断言)
config.headers!.Authorization = `Bear ${token}`;
return config;
});
// 响应拦截器
request.interceptors.response.use(undefined, (error) => {
if (error.response.status === 401) {
// ....
}
return Promise.reject(error);
});
export default request;
声明接口
声明接口是,需声明 接口所需参数的类型,接口响应值类型
如下封装一个 登录接口
import request from "@/utils/request";
import { Token } from "./../types/data.d";
// 声明接口所需参数类型
export type LoginParams = {
mobile: string;
code: string;
};
// 声明接口响应类型
type LoginResponse = {
message: string;
data: Token;
};
// 登录接口
export const loginAPI = (values: LoginParams) => {
// 发送请求
return request.post<LoginResponse>("/authorizations", values);
};
封装为 asyncThunk
封装为 asyncThunk 以便 获取数据后,直接存入redux中
import { LoginParams } from "../../api/index";
import { createAsyncThunk } from "@reduxjs/toolkit";
import { loginAPI } from "@/api";
import { setToken } from "@/utils/token";
// 登录
export const login = createAsyncThunk(
"login/token",
async (params: LoginParams) => {
// 发起请求
const response = await loginAPI(params);
// 拿到返回数据
const tokens = response.data.data;
// 设置本地token
setToken(tokens);
// redux中保存toekn
return tokens;
}
);
响应拦截器需修改 Promise返回值 时,如何处理
// 响应拦截器
request.interceptors.response.use(
(response: AxiosResponse) => {
return response.data;
}
);
需给请求传入 第二个类型参数
请求方法的类型参数中,可以传三个类型参数,上面的案例只传了一个类型参数
- 第一个类型参数:该请求获取数据类型
- 第二个类型参数:该方法Promise结果最终返回的数据类型(默认为第一个类型参数
<T>的AxiosResponse<T>类型,若响应拦截器中不进行修改,默认类型其实是正确的)
如下代码中:
- 第一个
GetCodeResponse为返回类型,如果只传这个,会通过AxiosResponse<T>自动推断第二个类型参数 - 因为我们拦截器将
AxiosResponse进行了修改,所以我们需要直接传第二类型,之前自动推断的已经不正确了
// 声明接口响应类型
type GetCodeResponse = {
message: string;
data: null;
};
// 短信验证码
export const getCodeAPI = (mobile: number) => {
// 发送请求,
// 第一个GetCodeResponse为返回类型,如果只传这个,会通过AxiosResponse<T>自动推断第二个类型参数
// 因为我们拦截器将 AxiosResponse 进行了修改,所以我们需要直接传第二类型,之前自动推断的已经不正确了
return request.get<GetCodeResponse, GetCodeResponse>("sms/codes/" + mobile);
};
效果对比
原本调用getCodeAPI的提示和响应拦截器改过的结果不一致:
现在,传入第一个类型参数后:这样就和拦截器返回结果一致了!