Skip to content

Instantly share code, notes, and snippets.

@ca0v
Last active May 30, 2024 18:31
Show Gist options
  • Save ca0v/73a31f57b397606c9813472f7493a940 to your computer and use it in GitHub Desktop.
Save ca0v/73a31f57b397606c9813472f7493a940 to your computer and use it in GitHub Desktop.
Typescript Debounce
// ts 3.6x
function debounce<T extends Function>(cb: T, wait = 20) {
let h = 0;
let callable = (...args: any) => {
clearTimeout(h);
h = setTimeout(() => cb(...args), wait);
};
return <T>(<any>callable);
}
// usage
let f = debounce((a: string, b: number, c?: number) => console.log(a.length + b + c || 0));
f("hi", 1, 1);
f("world", 1);
@oburakevych
Copy link

oburakevych commented May 9, 2024

The correct type for timeout is ReturnType<typeof setTimeout> not number

The return value is a positive integer which identifies the timer created by the call to setTimeout(). In the browser correct call is window?.setTimeout().

https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value

@sylvainpolletvillard
Copy link

Still no solution that solves my context issue

@Pyotato
Copy link

Pyotato commented May 30, 2024

 function debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
  func: F,
  waitFor: number,
): (...args: Parameters<F>) => void {
  let timeout: ReturnType<typeof setTimeout>;
  
  return (...args: Parameters<F>): void => {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), waitFor);
  };
}

const person = {
  name: 'Jack',
  speak: function say(sec:number){
  debounce(()=>console.log(`My name is ${this.name} , debounced ${sec}`),sec)();
  }

}

person.speak(3_000);
debounce(()=>console.log('hehe'),100)();
debounce(()=>console.log('hehe 1_000'),1_000)();
person.speak(4_000);

not sure if this solution addresses the issue but works

playground

@sylvainpolletvillard
Copy link

You create a new function every time, therefore person.speak is not debounced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment