打字稿默认通用类型

时间:2020-04-28 09:53:44

标签: typescript generics

假设我想围绕axios创建一个分页包装。在这个包装器中,我将能够转换数据有效载荷,并添加多个其他转换器以获得最后一页或项目总数。

对于基本用法,我还需要默认参数(有效载荷数据=数据)

但是如果没有提供默认功能,我会遇到麻烦

这是我到目前为止提出的:

type PaginateOptions<T, Payload = T[]> = {
  url: string;
  currentPage?: number;
  resultsPerPage?: number;
  range?: number;
  updateFn: (page?: number) => void;
  options: Ref<Record<string | number, string | number>>;
  dataTransformer: (payload: Payload) => Payload extends T[] ? Payload : T[];
  totalPageTransformer: (payload: Payload) => number;
  totalTransformer: (payload: Payload) => number;
}

// T refers to the data type I'm fetching, and Payload what the Axios payload looks like
export default function usePaginate<T, Payload>({
  url,
  currentPage: page = 1,
  updateFn = () => {},
  options = ref({}),
  // Error here: Type 'Payload' is not assignable to type 'Payload extends T[] ? Payload : T[]'
  dataTransformer = (results) => results,
  totalPageTransformer,
  totalTransformer,
  resultsPerPage = 25,
  range = 5,
}: PaginateOptions<T, Payload>) {
  const data = ref<T[]>([]); // I'm storing the fetched data here
  /* ... */
  return { data };
}

有效负载示例:

// Basic payload, with separated data and pagination info
axios.get<Payload>(url, options)
  .then(({ data }) => {
    // data is of type Payload
    console.log(data);
    /*
    {
      "data": [{ "name": "A", "id": 1 }, { "name": "B", "id": 2 }, { "name": "B", "id": 3 }],
      "pagination": {
        "total": 15,
        "page": 1,
        "resultsPerPage": 3
      }
    }
    */
  });

axios.get<Payload>(url, options)
  .then(({ data }) => {
    // data is of type Payload
    console.log(data);
    /*
    No pagination data, I can provide it locally if I know it is fixed (search by first letter => always 26)
    [{ "name": "A", "id": 1 }, { "name": "B", "id": 2 }, { "name": "B", "id": 3 }]
    */
  });

0 个答案:

没有答案