There is a handy feature in Lodash called update, which allows for easy object manipulation:
const obj = {}
_.update(obj, 'a.b.c', prev => prev ? 1 : 0)
console.log(obj) // { a: { b: { c: 0 } } }
By providing a path (as a string) as the second argument, the update
function recursively creates the path and sets the value of the last item based on the updater's return value.
Unfortunately, there are limitations with typing support:
const obj = { a: { b: { c: "hello world" } } };
_.update(obj, "a.b.c", (prev) => (prev ? 1 : 0));
console.log(obj); // { a: { b: { c: 0 } } }
The type of prev
is identified as any
, posing potential risks. This led me to explore creating my own alternative to Lodash's update
utility after encountering difficulties in typing paths. I came across an answer that provided insight but found it overwhelming, especially when dealing with computed keys.
This prompted the creation of a custom wrapper for _.update
:
export function mutate<T extends object, P extends object = object>(
obj: T,
path: P,
updater: (prev: ValueOf<T>) => ValueOf<T>
): T {
const actualPath = Object.keys(path)
.map((o) => path[o as keyof P])
.join(".");
return _.update(obj, actualPath, updater);
}
const obj = { a: { b: { c: 123 } } };
const x = "a";
const y = "b";
const z = "c";
mutate(obj, { x, y, z }, (prev) => 123);
While some progress has been made with mutate
catching type mismatches, recursion remains a challenge leaving me puzzled about next steps.
Queries
- Is there a way to determine the type of a computed property like illustrated above?
- If yes, how can this be achieved?
- How can recursion be implemented, if feasible?
- If you're familiar with any other tool or npm package addressing this issue of object updates, please share your suggestions.