ts如何优雅的处理返回值类型问题

714 阅读1分钟
 写axios时发现返回值类型会丢失

image.png

如何优雅的解决这个问题呢,当我们封装axios的时候就会发现直接用axios实例去.then时发现他的res的类型为AxiosResponse,这个类型axios抛了出来
export interface AxiosResponse<T = any, D = any>  {
  data: T;
  status: number;
  statusText: string;
  headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
  config: AxiosRequestConfig<D>;
  request?: any;
}

看这个类型可以发现他的data其实就是后端返回值的类型,这个类型需要通过第一个泛型传递过去,我们发现它还有第二个泛型D这个D又是什么呢我们可以去看AxiosRequestConfig这个类型
export interface AxiosRequestConfig<D = any> {
  url?: string;
  method?: Method | string;
  baseURL?: string;
  transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
  transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
  headers?: RawAxiosRequestHeaders;
  params?: any;
  paramsSerializer?: ParamsSerializerOptions;
  data?: D;
  ....
}
通过查看axios中的这个类型我们就会发现AxiosRequestConfig的泛型其实就是我们传递参数的类型所以我们可以通过这种方式去封装一下
我们可以先对aixos的实例进行封装
import axios, { AxiosInstance } from "axios";
export class Interceptors {
  instance: AxiosInstance;
  constructor() {
    this.instance = axios.create({
      // baseURL: baseURL,
      // baseURL: "http://192.168.48.97:9999",
    });
  }
  // 初始化拦截器
  init() {
    // 请求接口拦截器
    this.instance.interceptors.request.use(
      (config) => {
        return config;
      },
      (err) => {
        console.error(err);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response) => {
        return response;
      },
      (error) => {
        return Promise.resolve(error);
      }
    );
  }
  // 返回一下
  getInterceptors() {
    this.init()
    return this.instance;
  }
}
处理好axios实例之后我们可以对axios进行二次封装解决返回值问题
import { AxiosInstance, AxiosRequestConfig, AxiosResponse,AxiosError ,AxiosPromise} from "axios";

interface successType<T = any> {
    code:number,
    message:string,
    result:T,
    status:number,
}

class HttpServer {
  axios: AxiosInstance;
  constructor() {
    this.axios = new Interceptors().getInterceptors();
  }
  request<T,K = any>(config: AxiosRequestConfig<T>):AxiosPromise<successType<K>> {
    return new Promise((resolve, reject) => {
      this.axios(config).then((res:AxiosResponse<successType<K>,T>) => {
        resolve(res);
      }).catch((err:AxiosError) => {
        reject(err)
      });
    });
  }
}

const http = new HttpServer()

export default http

这样我们就可以通过泛型去解决返回值类型了快让我们试一下吧
const findByNameOrPhone = <K>(data:{
    pageIndex?: number,
    row?: number,
    flag:'TIME' | 'POLL',
    sessionId?: number,
    studentInfo?: string
}) => HttpServer.request<typeof data,K>({
    method: 'POST',
    url: url + '/xxxx',
    data
})

image.png

很好我们已经拿到返回值的类型啦,快来试一下吧