export interface TimedCacheOptions { timeout: number; useTimer: boolean; createKey: (args: string[]) => string; } export function timedCache string>( fn: T, { timeout, useTimer, createKey }: TimedCacheOptions ) { const cache = new Map(); let prevTime = Infinity; let shouldClean = false; const get = (...args: string[]) => { if (!shouldClean && useTimer) { setTimeout(() => { shouldClean = false; cache.clear(); }, timeout); } shouldClean = true; const current = Date.now(); if (current - prevTime >= timeout && !useTimer) { cache.clear(); } prevTime = current; const key = createKey(args); let value; if (!cache.has(key)) { value = fn(...args); cache.set(key, value); } else { value = cache.get(key); } return value; }; return { get: get as T, cache, }; }