Skip to content

Instantly share code, notes, and snippets.

@slikts
Last active July 15, 2018 10:44
Show Gist options
  • Save slikts/19b30ffc370fc03b4a898f4bf1f6f7ad to your computer and use it in GitHub Desktop.
Save slikts/19b30ffc370fc03b4a898f4bf1f6f7ad to your computer and use it in GitHub Desktop.
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