TypeScript Debounce Function
This package provides a robust TypeScript implementation of the debounce function, designed to limit the rate at which a function can be called. It is currently at version 5.0.0 and sees releases driven by feature enhancements and necessary fixes, rather than a strict schedule. Key features include full TypeScript support with improved type inference, cancellation functionality, an optional `maxWait` parameter to force execution after a maximum delay, and comprehensive Promise integration, allowing debouncing of promise-returning functions and returning promises from debounced calls. It differentiates itself by being TypeScript-first, directly addressing common debounce use cases with strong typing, and offering flexibility similar to popular utility libraries like Lodash but with a smaller footprint and modern ESM support.
Common errors
-
Argument of type 'any' is not assignable to parameter of type 'Event'.
cause Improved type inference in `ts-debounce` v4.0.0 and above now provides more specific types for function arguments, removing reliance on `any`.fixUpdate the type signature of your debounced function's arguments to match the expected specific type (e.g., `(event: Event)`). For example, `debounce((event: Event) => { /* ... */ }, 300);` -
TypeError: Cannot read property 'debounce' of undefined
cause This typically occurs in CommonJS environments when attempting to `require('ts-debounce')` and expecting a default export, or attempting to use `const debounce = require('ts-debounce')` instead of destructuring.fixEnsure you are destructuring the named export: `const { debounce } = require('ts-debounce');`. If using ES Modules, prefer `import { debounce } from 'ts-debounce';`. -
ReferenceError: Promise is not defined
cause Running `ts-debounce` v3.0.0 or higher in a JavaScript environment that lacks a global `Promise` object (e.g., older browsers or Node.js without a polyfill).fixInclude a `Promise` polyfill (e.g., from `core-js` or `es6-promise`) in your application bundle to provide the necessary global `Promise` implementation.
Warnings
- breaking Version 5.0.0 introduces the use of the `Awaited` type to prevent `Promise<Promise<T>>` in promise-returning debounced functions. While an improvement, this change might subtly alter the inferred return types, potentially causing existing type checks to break if they were expecting less specific types.
- breaking Version 4.0.0 significantly improved type inference for arguments passed to the debounced function. This means types that were previously inferred as `any` (e.g., event objects in event listeners) are now much more specific. If your existing code relied on the looser `any` type, it might now trigger TypeScript compilation errors.
- gotcha Starting from version 3.0.0, `ts-debounce` introduced Promise support. This functionality relies on the global `Promise` object being available in the execution environment. In older browser environments or Node.js versions, a global `Promise` polyfill might be required.
- gotcha The `isImmediate` option, when set to `true`, causes the `originalFunction` to be invoked immediately on the first call, and subsequent calls are debounced. If not fully understood, this can lead to unexpected immediate executions when the intention was a delayed one.
Install
-
npm install ts-debounce -
yarn add ts-debounce -
pnpm add ts-debounce
Imports
- debounce
import { debounce } from 'ts-debounce'; - debounce
import debounce from 'ts-debounce';
- debounce
const debounce = require('ts-debounce');const { debounce } = require('ts-debounce'); - DebouncedFunction
import type { DebouncedFunction } from 'ts-debounce';
Quickstart
import { debounce } from 'ts-debounce';
// Example 1: Basic debouncing for input handling
function logInput(value: string) {
console.log('Debounced input:', value);
}
const debouncedLog = debounce(logInput, 500);
// Simulate rapid input events
debouncedLog('a');
debouncedLog('ap');
debouncedLog('app');
// This call will execute 500ms after the last 'app' call
setTimeout(() => debouncedLog('apple'), 600);
// Example 2: Debouncing an asynchronous function with cancellation
const fetchUserData = async (userId: string): Promise<string> => {
console.log(`Fetching data for ${userId}...`);
return new Promise(resolve => setTimeout(() => resolve(`Data for ${userId}`), 1000));
};
const debouncedFetch = debounce(fetchUserData, 300);
async function testAsyncDebounce() {
console.log("Calling async debounced function rapidly...");
const p1 = debouncedFetch('user1');
const p2 = debouncedFetch('user2');
const p3 = debouncedFetch('user3'); // This will be the one that gets executed if not cancelled
setTimeout(() => {
debouncedFetch.cancel(); // Cancel the pending 'user3' call
console.log("Debounced fetch cancelled.");
}, 400); // This will happen before 'user3' would execute
try {
// p1 and p2 will reject if the final call is cancelled
await Promise.allSettled([p1, p2, p3]);
console.log("Promises settled (some may be rejected due to cancellation).");
} catch (e: any) {
console.warn("An unexpected error occurred during async debounce test:", e.message);
}
}
testAsyncDebounce();