打字稿 axios 打字
Posted
技术标签:
【中文标题】打字稿 axios 打字【英文标题】:Typescript axios typings 【发布时间】:2021-07-27 16:08:07 【问题描述】:这是我的第一个问题,所以请告诉我如何改进。
我有以下 axios fetch 功能:
export enum RequestMethod
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
PATCH = 'PATCH',
DELETE = 'DELETE',
export const fetchAxiosAPI = async (
url: string,
method: RequestMethod,
data = ,
options =
) =>
let result;
try
result = await axios(
method,
url: `$process.env.REACT_APP_API_URL/$url`,
data,
...options,
validateStatus: () =>
return true;
,
).then(response => response.data);
catch (err)
return null;
const errorStatus = result.error.status;
if (errorStatus === 401)
localStorage.removeItem('access_token');
history.push('/login');
if (errorStatus === 404)
history.replace(NOT_FOUND);
if (errorStatus === 500)
history.replace(INTERNAL_SERVER_ERROR);
return result;
;
它看起来很丑,使用 await 和 then(我们不应该使用)。 我有两个问题:
-
如何将 typescript 泛型作为参数传递给此函数,以推断 typescript 类型以响应 API 调用 (Promise)?我找到了使用 axios[methodName] 的示例:
axios.get
(url)
但还没有找到使用通用 axios 方法传递泛型的方法,就像我的代码示例中提供的那样。
-
如何处理错误状态、catch 块和 await/then - 使用其中的 1 个?基本上,如何重写
fetchAxiosAPI
函数。
【问题讨论】:
【参考方案1】:如果我正确阅读了文档和index.d.ts
文件,axios.request
应该这样做。来自文档:
为方便起见,为所有支持的请求方法提供了别名。
axios.request(config)
...
在index.d.ts
:
export interface AxiosInstance (config: AxiosRequestConfig): AxiosPromise; (url: string, config?: AxiosRequestConfig): AxiosPromise; defaults: AxiosRequestConfig; interceptors: request: AxiosInterceptorManager<AxiosRequestConfig>; response: AxiosInterceptorManager<AxiosResponse>; ; getUri(config?: AxiosRequestConfig): string; request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>; get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; delete<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; head<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; options<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>; post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>; put<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>; patch<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>; export interface AxiosStatic extends AxiosInstance create(config?: AxiosRequestConfig): AxiosInstance; Cancel: CancelStatic; CancelToken: CancelTokenStatic; isCancel(value: any): boolean; all<T>(values: (T | Promise<T>)[]): Promise<T[]>; spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R; isAxiosError(payload: any): payload is AxiosError; declare const axios: AxiosStatic;
注意request
像axios
函数本身一样只接受配置对象,但与axios
不同的是,它具有您在get
、post
等上看到的泛型类型参数。
所以像这样,见***
cmets:
export const fetchAxiosAPI = async <T>(
// ^^^−−−−−−−−−−− *** type parameter
url: string,
method: RequestMethod,
data = ,
options =
) =>
let result: T;
try
// *** Get the response using `axios.request` with the type argument
const response = await axios.request<T>(
method,
url: `$process.env.REACT_APP_API_URL/$url`,
data,
...options,
validateStatus: () =>
return true;
,
);
// *** Get the result
result = response.data;
catch (err)
return null; // *** This is poor practice; allow the error to propagate
// or throw a new error
const errorStatus = result.error.status;
if (errorStatus === 401)
localStorage.removeItem('access_token');
history.push('/login');
if (errorStatus === 404)
history.replace(NOT_FOUND);
if (errorStatus === 500)
history.replace(INTERNAL_SERVER_ERROR);
return result;
;
【讨论】:
谢谢,原来我需要使用 axios.request。用 tr/catch 块包装我的函数是一种好习惯吗? @MindaugasN - 函数 call,是的,或者对调用它的函数的调用,或者调用它的函数,等等。你不想隐藏那些其他函数发生错误的事实,或者强制它们都检查返回值。相反,在可能的***别有一个错误处理程序(通常是启动调用链的事件处理程序或类似的)。以上是关于打字稿 axios 打字的主要内容,如果未能解决你的问题,请参考以下文章