Mixed utilities
Deep clone, deep equality, shuffle, coalesce. Import from @mongez/reinforcements.
clone — deep copy
clone<T>(value: T): THandles Date, RegExp, Error (with own props), Map, Set, typed arrays, ArrayBuffer, and circular references via internal WeakMap. Non-plain class instances are returned by reference (cloning user constructors is out of scope — call your own .clone() if you have one).
const a: any = { name: "Ada" };a.self = a; // circularconst copy = clone(a);copy.self === copy; // true — circular ref preserved
clone(new Date(0)); // new Date instance, same timeclone(/abc/gi); // new RegExp, same source/flagsclone(new Map([["k", 1]])); // new Map, deep-cloned values
const err = new TypeError("nope");(err as any).meta = { detail: true };clone(err).meta; // { detail: true } — own props preservedareEqual — deep value equality
areEqual(a: any, b: any): booleanNon-mutating deep equality. Respects element order in arrays. Handles Date, RegExp, Map, Set, and circular references.
areEqual({ a: 1 }, { a: 1 }); // trueareEqual([1, 2, 3], [1, 2, 3]); // trueareEqual([1, 2, 3], [3, 2, 1]); // false — order matters
areEqual(new Date(0), new Date(0)); // trueareEqual(/abc/g, /abc/g); // trueareEqual(new Set([1, 2]), new Set([2, 1])); // true (Set equality)
const a: any = { x: 1 }; a.self = a;const b: any = { x: 1 }; b.self = b;areEqual(a, b); // true — circular-safeThis is a value comparator, not a type/shape predicate. For predicates like
isEmpty/isPlainObject, use@mongez/supportive-is.
shuffle — Fisher–Yates
shuffle<T>(value: T[], options?: { mutate?: boolean }): T[]shuffle(value: string, options?: { mutate?: boolean }): stringNon-mutating by default. Pass { mutate: true } to shuffle the array in place.
shuffle([1, 2, 3, 4]); // e.g. [3, 1, 4, 2]; original untouchedshuffle("hello"); // e.g. "lehlo"shuffle(arr, { mutate: true }); // shuffles in place, returns arrcoalesce — first non-nullish
coalesce<T>(...values: Array<T | null | undefined>): T | undefinedReturns the first value that isn’t null or undefined. Falsy-but-defined values (0, "", false, NaN) pass through — unlike ||.
coalesce(null, undefined, "first"); // "first"coalesce(undefined, 0, "x"); // 0coalesce(undefined, "", "x"); // ""coalesce(null, undefined); // undefined