type Procedure = (...args: any[]) => void export function debounce( func: F, waitMilliseconds: number ): { (this: ThisParameterType, ...args: Parameters): void cancel: () => void } { let timeoutId: ReturnType | null = null const debouncedFunction = function ( this: ThisParameterType, ...args: Parameters ): void { if (timeoutId !== null) { globalThis.clearTimeout(timeoutId) } timeoutId = globalThis.setTimeout(() => { timeoutId = null func.apply(this, args) }, waitMilliseconds) } debouncedFunction.cancel = (): void => { if (timeoutId !== null) { globalThis.clearTimeout(timeoutId) timeoutId = null } } return debouncedFunction }