export type DebouncedFunction void> = ((...args: Parameters) => void) & { cancel: () => void } /** * Returns a debounced function that delays invoking `fn` until after `delayMs` has elapsed * since the last call. The returned function has a `cancel()` method to clear pending invocations. */ export function debounce void>( fn: T, delayMs: number | (() => number), ): DebouncedFunction { let timeoutId: ReturnType | undefined const debounced = (...args: Parameters) => { if (timeoutId !== undefined) { clearTimeout(timeoutId) } const delay = typeof delayMs === 'function' ? delayMs() : delayMs timeoutId = setTimeout(() => { timeoutId = undefined fn(...args) }, delay) } debounced.cancel = () => { if (timeoutId !== undefined) { clearTimeout(timeoutId) timeoutId = undefined } } return debounced }