debounce wraps a function so that repeated calls reset a timer; the wrapped callback only fires once the caller has gone quiet for delay milliseconds. Typical uses: search-as-you-type inputs, window resize handlers, autosave triggers.
export function debounce<T extends (...args: unknown[]) => void>(
fn: T,
delay: number,
): (...args: Parameters<T>) => void {
let timerId: Nullable<ReturnType<typeof setTimeout>> = null;
return (...args: Parameters<T>) => {
if (timerId !== null) clearTimeout(timerId);
timerId = setTimeout(() => {
fn(...args);
}, delay);
};
}
Notes
- The generic constraint
T extends (...args: unknown[]) => voidkeeps the argument types intact while enforcing a void return — the caller's return value is discarded by design. - Each call clears the previous timer, so only the last invocation in a burst executes.