打字稿 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;

注意requestaxios 函数本身一样只接受配置对象,但与axios 不同的是,它具有您在getpost 等上看到的泛型类型参数。

所以像这样,见*** 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 打字的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个打字稿程序永无止境?

打字稿捆绑器到打字稿文件

打字稿打字,打字文件夹是啥

反应打字稿打字不起作用

为我的反应打字稿组件库生成/维护打字稿定义文件

打字稿:通过打字重命名obj属性