Skip to main content

set()

set<T>(object, path, value): T

Sets the value at path of object, returning a new object (immutable).

WHY WRAPPING NATIVE?

We prefer to wrap this method to ensure Immutability and safe property access. See Design Philosophy

note

Creates intermediate objects/arrays as needed based on path structure.


Type Parametersโ€‹

T: T = anyโ€‹

The type of the input object.


Parametersโ€‹

object: Tโ€‹

The object to set the value in.

path: string | symbol | (string | number | symbol)[]โ€‹

Property path (dot notation string, symbol, or array of keys).

value: anyโ€‹

The value to set.


Returns: Tโ€‹

A new object with the value set at the specified path.


See Alsoโ€‹

get


Sinceโ€‹

2.0.0


Noteโ€‹

Uses structuredClone for performance; falls back to deepClone for symbol keys.


Performanceโ€‹

O(n + m) time & space where n is object size, m is path length. structuredClone when possible (faster), deepClone only for symbol keys. Early returns for null/empty path.


Also known asโ€‹

assocPath (Ramda) ยท set (Lodash, es-toolkit, Remeda, Radashi, Modern Dash) ยท โŒ (Effect, Antfu)


Exampleโ€‹

const obj = { a: { b: { c: 3 } } };

set(obj, 'a.b.c', 42); // => { a: { b: { c: 42 } } }
set(obj, ['a', 'b', 'd'], 'new'); // => { a: { b: { c: 3, d: 'new' } } }

// Create nested structures automatically
set({}, 'user.profile.name', 'John');
// => { user: { profile: { name: 'John' } } }

// Array creation with bracket notation
set({}, 'items[0].value', 42);
// => { items: [{ value: 42 }] }

How it works?โ€‹

Immutably sets a value at a nested path, returning a new object.

Immutabilityโ€‹

Auto-Creationโ€‹

Creates intermediate objects/arrays as needed:

Array Creationโ€‹


Use Casesโ€‹

Update nested data safely ๐Ÿ“Œโ€‹

Set a value at a deep path, creating intermediate objects if missing. Returns a new object (immutable). Essential for reducer-like state updates.

const updatedState = set(state, 'users[0].isActive', true);

Create deep structuresโ€‹

Build a deeply nested object from scratch by setting a single path on an empty object. Useful for converting flat keys to nested objects.

const obj = set({}, 'a.b.c', 'value');
// { a: { b: { c: 'value' } } }

Append to arraysโ€‹

Use numeric indices in the path to create or update array elements.

const list = set([], '[0].name', 'First');
// [{ name: 'First' }]

Update dynamic form fields by pathโ€‹

Handle onChange events for deeply nested form fields using a dynamic path. The standard pattern for complex forms with nested objects (address, billing, etc.).

const [formData, setFormData] = useState({
name: "",
address: { street: "", city: "", zip: "" },
billing: { card: "", expiry: "" },
});

const handleChange = (path: string, value: string) => {
setFormData((prev) => set(prev, path, value));
};

// In JSX:
// <input onChange={(e) => handleChange("address.city", e.target.value)} />
// <input onChange={(e) => handleChange("billing.card", e.target.value)} />