首页 > 解决方案 > 打字稿默认通用类型

问题描述

假设我想围绕 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 }]
    */
  });

标签: typescriptgenerics

解决方案


推荐阅读