使用函数传递泛型,在Typescript中应用

tyu7yeag  于 2023-01-10  发布在  TypeScript
关注(0)|答案(1)|浏览(88)

我正在编写一个个人项目(我最初是以Javascript开始这个项目的),在这个项目中必须发出一些http请求。为了做到这一点,我决定使用Axios。因此,我创建了一个名为http.js的文件,包含以下内容。

import axios from 'axios';

const baseURL = '/api';

const requestWrapper = async (request, { url, options, data }) => {
  const config = { baseURL, ...options };

  const requestObject = await request.apply(
    this,
    data ? [url, data, config] : [url, config]
  );
  const requestData = requestObject.data;

  return { status: requestObject.status, data: requestData };
};

const get = async (url, options) => {
  try {
    return await requestWrapper(axios.get, { url, options });
  } catch (error) {
    return error.response;
  }
};

const remove = async (url, options) => {
  try {
    return await requestWrapper(axios.delete, { url, options });
  } catch (error) {
    return error.response;
  }
};

const post = async (url, data, options) => {
  try {
    return await requestWrapper(axios.post, { url, data, options });
  } catch (error) {
    return error.response;
  }
};

const put = async (url, data, options) => {
  try {
    return await requestWrapper(axios.put, { url, data, options });
  } catch (error) {
    return error.response;
  }
};

const patch = async (url, data, options) => {
  try {
    return await requestWrapper(axios.patch, { url, data, options });
  } catch (error) {
    return error.response;
  }
};

export { get, remove, post, put, patch };

我在上一个代码片段中所做的是将每个http请求封装到一个名称相似的函数中,这样做是为了在http客户端库(Axios)发生变化时简化代码。
问题是,现在我想将此文件转换为Typescript。我遇到的具体问题是,在前面的代码中,我创建了一个 Package 器函数,因为每个http函数的调用都非常相似,此 Package 器函数应接收泛型T,以便通过Axios函数传递它,从而键入响应。但是,我不知道如何传递此泛型,因为在以下函数中:

const requestWrapper = async (request, { url, options, data }) => {
  const config = { baseURL, ...options };

  const requestObject = await request.apply(
    this,
    data ? [url, data, config] : [url, config]
  );
  const requestData = requestObject.data;

  return { status: requestObject.status, data: requestData };
};

具体而言:

const requestObject = await request.apply(
    this,
    data ? [url, data, config] : [url, config]
  );

我不知道如何指定泛型。我该怎么做?
我搜索了一下,但没有找到像我的问题这样的具体问题。我想删除内部 Package 器,并在其特定的封装函数中调用每个Axios函数。

9udxz4iz

9udxz4iz1#

由于Function#apply是弱类型的,如果你想要一个更强的类型,你必须使用类型转换:

const requestObject = await (request.apply(
        this,
        data ? [url, data, config] : [url, config]
    ) as ReturnType<typeof request<T>>)

完整代码:

const requestWrapper = async <T>(request:
    typeof axios.get |
    typeof axios.post |
    typeof axios.put |
    typeof axios.patch |
    typeof axios.delete
    , { url, options, data }) => {
    const config = { baseURL, ...options };

    const requestObject = await (request.apply(
        this,
        data ? [url, data, config] : [url, config]
    ) as ReturnType<typeof request<T>>)
    const requestData = requestObject.data;

    return { status: requestObject.status, data: requestData };
};

相关问题