Skip to content

Function: isSerializableValue()

isSerializableValue(value, ancestors?): value is SerializableValue

True when value survives a JSON round trip with no loss and no coercion.

Stricter than “JSON.stringify did not throw”, because that succeeds while silently CHANGING the value: a Date becomes a string, NaN and Infinity become null, a Map becomes {}, and undefined disappears from an object or turns into null inside an array. Each of those reaches the far side as something other than what was sent, so all of them are rejected here.

Rejected: non-finite numbers, undefined, functions, symbols, bigints, class instances and anything else with a prototype other than Object.prototype or null (Date, Map, Set, RegExp, Buffer), and any object graph containing a cycle. Accepted: strings, booleans, null, finite numbers, plain objects, arrays, and nestings of those.

Narrows to SerializableValue rather than asserting, so it also serves as the validator for untrusted input - a request body, a decoded notification payload - where the answer should be a 400 and not a throw. Never throws.

Distinct from deepEqual’s notion of comparable: that one HANDLES Date/Map/Set structurally, while this one rejects them precisely because JSON cannot carry them.

unknown

Set<object> = ...

Cycle-detection set for the recursive walk. Internal; callers pass one value.

value is SerializableValue

isSerializableValue({ a: [1, "x", null] }); // true
isSerializableValue({ at: new Date() }); // false - would become a string
isSerializableValue(Number.NaN); // false - would become null