Skip to content

unflattenRecord

unflattenRecord(source, options?): Record<string, unknown>

Defined in: packages/core/src/object/unflatten-record.ts:84

Rebuild a nested record from one whose keys are delimiter-joined paths — the inverse of flattenRecord.

unflattenRecord(flattenRecord(x)) deep-equals x for any x whose keys contain neither the delimiter nor, below the top level, one of the three prototype-reaching names named further down. A key that does contain the delimiter is indistinguishable from nesting and is split: { "a.b": 1 } becomes { a: { b: 1 } }, whatever the input meant by it.

Where two keys disagree about a segment’s shape — "a" holding 1 beside "a.b" holding 2 — the deeper key replaces the scalar with a container, and the entries are applied in Object.keys order, so the last one wins.

A key with two or more segments is a path walk, and one whose segments include __proto__, constructor or prototype is dropped whole: the intermediate reads of such a walk reach a prototype shared with every other object, before anything is assigned. A single-segment key is an ordinary leaf write and is kept, stored as an own entry by setRecordEntry — a record of environment variables should still be able to hold one named constructor.

Time is linear in the total length of the input keys plus the number of segments walked. Memory is the rebuilt record plus one segment array per entry, which is released as each entry is written.

Readonly<Record<string, unknown>>

The one-level record to expand; it is not modified.

UnflattenRecordOptions

Delimiter and array rebuilding.

Record<string, unknown>

A new nested record.

unflattenRecord({ "key1.keyA": "v", "key2.a.b": 2 });
// { key1: { keyA: "v" }, key2: { a: { b: 2 } } }
unflattenRecord({ "hello.you.0": "x" });
// { hello: { you: { "0": "x" } } }
unflattenRecord({ "hello.you.0": "x" }, { buildArrays: true });
// { hello: { you: ["x"] } }
```;
## Throws
RangeError If the delimiter is empty.