Axios的封装报错(Argument of type ‘HYRequestConfig<T>‘ is not assignable to parameter of type ‘InternalAx)

在对axios拦截器封装时,报一个关于AxiosHeaders的类型继承错误,以下给出解决方案。

1、axios原始封装代码

type.ts (对interceptors封装的代码)

/* eslint-disable @typescript-eslint/no-explicit-any */
import {
  type AxiosRequestConfig,
  type InternalAxiosRequestConfig,
  type AxiosResponse,
} from "axios";

interface HInterceptors<T = AxiosResponse> {
  requestSuccessFn?: (
    config: InternalAxiosRequestConfig
  ) => InternalAxiosRequestConfig;
  requestFailureFn?: (err: any) => any;
  responseSuccessFn?: (res: T) => T;
  responseFailureFn?: (err: any) => any;
}

//针对AxiosRequestConfig配置进行扩展(在里面再次添加自定义interceptors拦截器)
export interface HRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HInterceptors<T>;
}


request.ts主代码逻辑

import axios from "axios";
import type { AxiosInstance } from "axios";
import type { HRequestConfig } from "./type";

class Request {
  instance: AxiosInstance;
  constructor(config: HRequestConfig) {
    this.instance = axios.create(config);

    this.instance.interceptors.request.use(
      (config) => {
        return config;
      },
      (err) => {
        return err;
      }
    );

    this.instance.interceptors.response.use(
      (res) => {
        return res.data;
      },
      (err) => {
        return err;
      }
    );

    //针对特定的hyRequest的实例添加拦截器
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    );
    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    );
  }

  //封装网络请求的方法
  request<T = any>(config: HRequestConfig<T>) {
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config);
    }
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          //单次响应成功的拦截处理
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res);
          }
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  get<T = any>(config: HRequestConfig<T>) {
    return this.request({ ...config, method: "GET" });
  }
  post<T = any>(config: HRequestConfig<T>) {
    return this.request({ ...config, method: "POST" });
  }
  delete<T = any>(config: HRequestConfig<T>) {
    return this.request({ ...config, method: "DELETE" });
  }
  patch<T = any>(config: HRequestConfig<T>) {
    return this.request({ ...config, method: "PATCH" });
  }
}

export default Request;

2、错误提示

  • 在request.ts自定义的拦截器部分报错
    在这里插入图片描述
    在这里插入图片描述

报错原因:

  • 查看axios的源码可知request的泛型为InternalAxiosRequestConfig,而自定义的HRequestConfig继承是AxiosRequestConfig,对应的headers不同。好了接下来直接给出解决方法。
    在这里插入图片描述
    在这里插入图片描述

3、解决方法

  • 步骤① 在type.ts中加上headers
...

export interface HRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HInterceptors<T>;
  headers?: AxiosRequestHeaders;
}
  • 步骤② 在request.ts中发送请求时将config类型转为InternalAxiosRequestConfig即可完成
... 

request<T = any>(config: HRequestConfig<T>) {
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(
        config as InternalAxiosRequestConfig
      );
    }

4、使用二次封装的axios发送请求

书写一个发送请求的index.ts

import HRequest from "./request";

const Request = new HRequest({
  baseURL: "http://codercba.com:9002",
  timeout: 10000,

  interceptors: {
    requestSuccessFn: (config) => {
      return config;
    },
  },
});

export default Request;

在前端页面中掉用封装的Request发起请求
在这里插入图片描述

控制台打印成功
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值