Debounce

Debouncing is a strategy used to improve the performance of a feature by controlling the time at which a function should be executed.

It creates a debounced function that delays invoking func until after wait milliseconds have elapsed since the last time the debounced function was invoked. The debounced function comes with a cancel method to cancel delayed func invocations.

The func is invoked with the last arguments provided to the debounced function. Subsequent calls to the debounced function return the result of the last func invocation.

type Callback = (...args: any[]) => void;

interface DebouncedCallback<Fn extends Callback> extends Fn {
  cancel(): void;
}

function debounce<Fn extends Callback>(wait: number, func: Fn) {
  let timeout: null | NodeJS.Timeout = null;

  function debounced(...args: any[]) {
    if (timeout !== null) clearTimeout(timeout);
    timeout = setTimeout(() => {
      func(...args);
      timeout = null;
    }, wait);
  }
  debounced.cancel = () => {
    if (timeout !== null) clearTimeout(timeout);
    timeout = null;
  };
  return debounced as DebouncedCallback<Fn>;
}