Типизируйте обёртку debounce, сохраняющую параметры обёрнутой функции
debounce принимает функцию и задержку и возвращает функцию, которая вызывает исходную только после того, как прошло ms без новых вызовов.
Требования:
месте вызова, — никаких any[] и Function;
- возвращаемая функция должна принимать ровно параметры обёрнутой функции, проверяемые в каждом
- повторный вызов до истечения задержки перезапускает таймер;
- возвращаемая функция возвращает
void.
export function debounce(fn, ms) {
// ваш код здесь
}
Допишите реализацию.
Сделайте обёртку обобщённой по типу функции — <T extends (...args: any[]) => void> — и дайте возвращаемой функции тип (...args: Parameters<T>) => void. Вызывающий получит исходный список параметров, проверяемый при каждом вызове, а не any[].
- ✗Типизировать обёрнутую функцию как
Function, теряя всякую проверку параметров - ✗Возвращать
(...args: any[]) => void, из-за чего вызывающий теряет исходную арность - ✗Забывать, что отложенный вызов не может вернуть результат обёрнутой функции
- →Как заодно сохранить получателя через
ThisParameterType<T>? - →Что изменится, если отложенный вызов должен вернуть
Promiseс результатом?
Обёртка обобщена по типу функции, а не по её аргументам. Тогда Parameters<T> вытаскивает исходный кортеж параметров, и он проверяется в каждом месте вызова.
export function debounce<T extends (...args: any[]) => void>(
fn: T,
ms: number,
): (...args: Parameters<T>) => void {
let timer: ReturnType<typeof setTimeout> | undefined;
return (...args: Parameters<T>): void => {
if (timer !== undefined) clearTimeout(timer);
timer = setTimeout(() => fn(...args), ms);
};
}
const save = debounce((id: number, body: string) => post(id, body), 300);
save(1, 'hi'); // ok
save('1', 'hi'); // Ошибка: 'string' не присваивается 'number'
T extends (...args: any[]) => void — только ограничение: any[] виден лишь внутри обёртки, наружу выходит точный Parameters<T>. Если типизировать fn как Function, то save(1, 'hi') и save('чепуха') пройдут одинаково.
Результат — void: в момент возврата вызов ещё не состоялся, возвращать нечего.