Skip to content

Instantly share code, notes, and snippets.

@tomiolah
Created June 14, 2023 13:40
Show Gist options
  • Save tomiolah/5e988ea5e78d8bc472d01db2ac98343b to your computer and use it in GitHub Desktop.
Save tomiolah/5e988ea5e78d8bc472d01db2ac98343b to your computer and use it in GitHub Desktop.
/** Interface that encompasses all props returned by the creator function */
interface ICBProps {
/** ID of the Timer that was created */
id: number;
/** Function that stops the created timer */
stop: () => void;
}
/** Type of a callback function that is aware of its own ID and can stop itself from within */
type CBFn = (stop: ICBProps["stop"], id: ICBProps["id"]) => void;
/** Type that matches both `setInterval` and `setTimeout` */
type TimerStartFn = (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
/** Type that matches both `clearInterval` and `clearTimeout` */
type TimerStopFn = (id: number | undefined) => void;
/** Generator that based on a cretor function and a stopper function generates a timer (timeout or interval) creator */
const createTimer =
(start: TimerStartFn, stop: TimerStopFn) =>
(cb: CBFn, timeoutMs: number): ICBProps => {
const stopper = (id: number) => () => stop(id);
const id = start(() => cb(stopper(id), id), timeoutMs);
return { id, stop: stopper(id) };
};
/** Wrapper function around `setInterval` and `clearInterval` that makes the callback aware of its ID, so it can be stopped from within or from the outside
*
* @return {number} `id` - ID of the interval
* @return {() => void} `stop` - function that stops the interval without needing to pass the ID
*/
export const createInterval = createTimer(setInterval, clearInterval);
/** Wrapper function around `setTimeout` and `clearTimeout` that makes the callback aware of its ID, so it can be stopped from within or from the outside
*
* @return {number} `id` - ID of the timeout
* @return {() => void} `stop` - function that stops the timeout without needing to pass the ID
*/
export const createTimeout = createTimer(setTimeout, clearTimeout);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment