Last active
July 15, 2018 10:44
-
-
Save slikts/19b30ffc370fc03b4a898f4bf1f6f7ad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Settable<A, B> { | |
set(key: A, value: B): this | |
} | |
interface Gettable<A, B> { | |
get(key: A): B | undefined | |
} | |
interface GenericMap<A, B> extends GetSettable<A, B> { | |
has(key: A): boolean | |
} | |
type GetSettable<A, B> = Settable<A, B> & Gettable<A, B> | |
const setDefault = <A, B, C extends GenericMap<A, B>>(key: A, value: B, target: C): C => | |
target.has(key) ? target : target.set(key, value) | |
const getSet = <A, B>(key: A, init: () => B, target: GetSettable<A, B>): B => | |
target.get(key) || <B>target.set(key, init()).get(key) | |
type Primitive = boolean | undefined | null | number | string | symbol | |
const isObject = (x: any): x is object => | |
x !== null && (typeof x === 'object' || typeof x === 'function') | |
class WeakishMap<A extends Primitive | object, B> implements GenericMap<A, B> { | |
readonly map: Map<Primitive, B> | |
readonly weakMap: WeakMap<object, B> | |
constructor() { | |
this.map = new Map() | |
this.weakMap = new WeakMap() | |
} | |
set(k: A, v: B): this { | |
if (isObject(k)) { | |
this.weakMap.set(k, v) | |
} else { | |
this.map.set(<Primitive>k, v) | |
} | |
return this | |
} | |
get(k: A): B | undefined { | |
if (isObject(k)) { | |
return this.weakMap.get(k) | |
} | |
return this.map.get(<Primitive>k) | |
} | |
has(k: A): boolean { | |
if (isObject(k)) { | |
return this.weakMap.has(k) | |
} | |
return this.map.has(<Primitive>k) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment