// eslint-disable-next-line @typescript-eslint/no-explicit-any type Procedure = (...args: any[]) => void; export function debounce( func: F, waitMilliseconds = 50, isImmediate?: boolean ): (this: ThisParameterType, ...args: Parameters) => void { let timeoutId: ReturnType | undefined; return function (this: ThisParameterType, ...args: Parameters) { // eslint-disable-next-line @typescript-eslint/no-this-alias const context = this; const doLater = function () { timeoutId = undefined; if (!isImmediate) { func.apply(context, args); } }; const shouldCallNow = isImmediate && timeoutId === undefined; if (timeoutId !== undefined) { clearTimeout(timeoutId); } timeoutId = setTimeout(doLater, waitMilliseconds); if (shouldCallNow) { func.apply(context, args); } }; }