Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import stringify from "fast-json-stable-stringify";
type ImmutablePrimitive =
| undefined
| null
| boolean
| string
| number
| Function;
export type Immutable<T> = T extends ImmutablePrimitive
? T
: T extends Array<infer U>
? ImmutableArray<U>
: T extends Map<infer K, infer V>
? ImmutableMap<K, V>
: T extends Set<infer M>
? ImmutableSet<M>
: ImmutableObject<T>;
export type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
export type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
export type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
export type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
const wm = new WeakMap<any>();
const m = new Map<string, any>();
function v<Value>(value: Value): Immutable<Value> {
if (typeof value !== "object" || value === null) {
// @ts-ignore
return value;
}
if (wm.has(value)) {
// @ts-ignore
return value;
}
const key = stringify(value);
if (m.has(key)) {
return m.get(key);
}
wm.set(value, key);
m.set(key, value);
// @ts-ignore
return value;
}
const a = v({ count: 1 });
const b = v({ count: 1 });
if (a === b) {
console.log(
"When `a` and `b` have value equality we also ensure that they have reference equality."
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment