小弟第一次用 ts 写项目,之前都是写一些 demo,下面有几个关于 axios 封装的问题,请求大佬们指点一下,感激不尽!
第一个问题是我在响应拦截里面做了一下处理,因为用的时候有的需要返回 code 以应对不同的情况,有的不需要直接用 data,就导致了不好定义req这个方法返回的类型,在使用的时候res.出来的是 axios 定义的 AxiosResponse 里面的东西,我想让它提示我返回的 data 里面自己定义的类型 或者是 没有 data 时候的 boolean?
// 后端返回的格式
{
  code: 0,
  data: xxx,
  errorMsg: xxx
}
// 使用的时候
const req = async (params: any) => {
  const res = await post(url, params);
  /** res.出来的提示是 AxiosResponse<any>的这些东西,axios 声明的如下
    export interface AxiosResponse<T = any>  {
      data: T;
      status: number;
      statusText: string;
      headers: any;
      config: AxiosRequestConfig;
      request?: any;
    }
  */
};
request.interceptors.request.use(
  config => {
    const headers = config.headers;
    const { extraConfig } = headers;
    if (extraConfig) {
      const { needLoading, needToken } = extraConfig;
      if (needLoading) // loading
      if (needToken) // token
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);
request.interceptors.response.use(
  response => {
    if (response.config.headers.extraConfig.needHandleError) {
      // 需要返回 code 以应对不同的情况
      return Promise.resolve(response.data);
    }
    const { data, errorMsg, code } = response.data;
    if (code === '00000') {
      if (data === null || data === undefined) {
        return Promise.resolve(true);
      } else {
        return Promise.resolve(data);
      }
    } else {
      return Promise.reject(new Error(errorMsg || 'Error'));
    }
  },
  error => {
    return Promise.reject(error);
  }
);
第二个问题就是我要配置一些自定义的内容进去,直接写在request的参数里面不行,因为AxiosRequestConfig没有定义这个额外的配置参数所以我的做法是写在了headers里面,这样就导致了请求的时候网页上也会看到我写的这个extraConfig: [object, object],我是不想看到这个的,我想到的一个是不是重新定义AxiosRequestConfig?这个该怎么写呢?
interface Config {
  needLoading?: boolean;
  needToken?: boolean;
  needHandleError?: boolean;
}
const dealConfig = (extraConfig?: Config) => {
  const defaultExtraConfig = {
    needLoading: true,
    needToken: true,
    needHandleError: false
  };
  if (typeof extraConfig === 'undefined') {
    extraConfig = defaultExtraConfig;
  } else {
    Object.keys(defaultExtraConfig).forEach(key => {
      if (!Object.prototype.hasOwnProperty.call(extraConfig, key)) {
        (extraConfig as Config)[key] = defaultExtraConfig[key];
      }
    });
  }
  return extraConfig;
};
export function post(url: string, params: object, extraConfig?: Config) {
  extraConfig = dealConfig(extraConfig);
  return request({
    url,
    method: 'post',
    data: params,
    headers: {
      extraConfig
    }
  });
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.