I hope that the debounce function can realize that the type of the returned function is exactly the same as the type of the passed function (whose return value is void
or Promise<void>
). I have write the following code
type VoidFunction = (...args: any[]) => void;
type PromiseVoidFunction = (...args: any[]) => Promise<void>;
export function debounce<T extends VoidFunction>(
fn: T,
delay: number
): (...args: Parameters<T>) => void;
export function debounce<T extends PromiseVoidFunction>(
fn: T,
delay: number
): (...args: Parameters<T>) => Promise<void>;
export function debounce<T extends(VoidFunction | PromiseVoidFunction)>(fn: T, delay: number) {
let timer: number | null = null;
return function (this: ThisParameterType<T>, ...args: Parameters<T>): Promise<void> | void {
if (timer) {
clearTimeout(timer);
}
if (fn.constructor.name === 'AsyncFunction') {
return new Promise<void>((resolve) => {
timer = setTimeout(() => {
timer = null;
Promise.resolve(fn.apply(this, args)).then(resolve);
}, delay);
});
}
timer = setTimeout(() => {
timer = null;
fn.apply(this, args);
}, delay);
};
};
However, when I use this debounce and passed a function has a Promise<void>
return type, typescript still infers the return type of the returned function as void