Skip to content

hash

Problem

You need a deterministic string from an object to use as a cache key, but JSON.stringify produces different output depending on key insertion order.

Solution

Use hash(value, options?) to always produce the same string regardless of key order. Object keys are sorted alphabetically; Date, RegExp, Set, Map, and bigint all have deterministic representations.

ts
import { hash } from '@vielzeug/arsenal';

const key1 = hash({ sort: 'asc', filter: { role: 'admin' } });
const key2 = hash({ filter: { role: 'admin' }, sort: 'asc' });
key1 === key2; // true

hash(new Set([3, 1, 2])); // '[Set:1,2,3]'
hash(new Date('2024-01-01T00:00:00Z')); // '[Date:2024-01-01T00:00:00.000Z]'
hash(
  new Map([
    ['b', 2],
    ['a', 1],
  ]),
); // '[Map:"a"=>1,"b"=>2]'
hash(42n); // '42n'

Circular references

ts
import { hash } from '@vielzeug/arsenal';

const o: Record<string, unknown> = { x: 1 };
o.self = o;
hash(o); // '{"self":[Circular],"x":1}'

Throw on class instances

ts
import { hash } from '@vielzeug/arsenal';

class Token {}
hash(new Token()); // String(instance) — default
hash(new Token(), { onClassInstance: 'throw' }); // throws TypeError

Pitfalls

  • Class instances coerce to String(instance) by default — pass { onClassInstance: 'throw' } to detect them.
  • undefined properties are omitted (same as JSON.stringify).
  • Map keys are sorted; output is deterministic regardless of insertion order.