-
-
Save ca0v/73a31f57b397606c9813472f7493a940 to your computer and use it in GitHub Desktop.
// 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); |
The correct type for
timeout
isReturnType<typeof setTimeout>
notnumber
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
Still no solution that solves my context issue
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
You create a new function every time, therefore person.speak is not debounced
@sylvainpolletvillard I landed here by chance and your initial example works fine for me when I simply ignore the Typescript error commenting the lines before 'this' - not sure if that is a valid solution for you though:
// @ts-expect-error: ignore
Sure, ignoring the error works to fix the error
debounce = <F extends (...args: Parameters<F>) => ReturnType<F>>( func: F, waitFor: number, ) => { let timeout: NodeJS.Timeout const debounced = (...args: Parameters<F>) => { clearTimeout(timeout) timeout = setTimeout(() => func(...args), waitFor) } return debounced }
The timeout type should be ReturnType<typeof setTimeout>
Another version,
await
the debounced function.The trick here (TS >=v4.6), is the generic
<T extends (...args: Parameters<T>) => ReturnType<T>>
: