interface IUnderlyingMap { has(key: K): boolean get(key: K): V | undefined delete(key: K): boolean set(key: K, value: V): void } interface IManagedMap { has(key: K): boolean get(key: K): V delete(key: K): boolean set(key: K, value: V): void getUnderlyingDataStructure(): IUnderlyingMap } type ValueFactory = (key: K) => V function mapFactory( factory: ValueFactory, map: IUnderlyingMap = new Map(), ): IManagedMap { return { has: (key: K): boolean => map.has(key), get: (key: K): V => { if (!map.has(key)) { map.set(key, factory(key)) } return map.get(key)! }, delete: (key: K): boolean => map.delete(key), set: (key: K, value: V): void => { map.set(key, value) }, getUnderlyingDataStructure: (): IUnderlyingMap => map, } } export = mapFactory