Допустим, я хотел бы создать оболочку для пагинации вокруг топора ios. В этой оболочке я смогу преобразовать полезную нагрузку данных и добавить несколько других преобразователей, чтобы получить последнюю страницу или общее количество элементов.
И мне также нужны параметры по умолчанию для самых базовых c использование (данные полезной нагрузки = данные)
Но у меня возникают проблемы при наборе функций по умолчанию, если они не предоставляются
Это то, что я до сих пор придумал:
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 }]
*/
});