English

Code Pool - Utilities

Set key-value on JS Object!

A cover featuring code examples of `setKeyValueOnObject` utility in JS with the text: "Js Object: Set Operation"
© Code pool series - utility to set key-value pairs on Objects in JavaScript and TypeScript.
0
13th Jul 2025

You can read about code-pool concepts on this link.

 

About this post

In this post, we’ll build a utility to handle adding or updating key-value pairs on an object — cleanly and flexibly! It’s a powerful, reusable tool to include in your projects. We'll also address common edge cases to ensure the final result is robust and production-ready.

 

Table of Contents

JavaScript Limitations When Setting Key-Value Pairs on an Object

By default, when you set a key-value pair on an object in JavaScript, it first checks if the key exists. If it doesn't, the key is added and the value is assigned. If the key does exist, the old value is simply replaced.

However, in real-world scenarios, you might want more control — such as extending the existing value, appending to it, or ignoring the update entirely. Handling these kinds of cases manually can become repetitive and error-prone, especially when dealing with complex or non-primitive values.

That’s where a reusable utility comes in handy. Let’s explore the utility and its capabilities in the next section.

Utility: setKeyValueOnObject()

Note: I’m going to import the isPlainObject utility we discussed in this post.

Here’s the isPlainObject code:

export const isPlainObject = (value: unknown): value is Record<string, unknown> =>
typeof value === 'object' && value !== null && !Array.isArray(value);

And here’s the JavaScript utility to properly handle both add and update operations!

import { isPlainObject } from './isPlainObject';
type UpdateMode = 'append' | 'replace' | 'extend' | 'ignore';
interface Options {
decodeURI?: boolean;
onConflict?: UpdateMode;
flatArraysOnAppend?: boolean;
removeArrayDuplicatedValues?: boolean;
}
export const setKeyValueOnObject = <
T extends object,
K extends keyof T,
V = unknown
>(
obj: T,
key: K,
value: V,
options: Options = {}
): T & Record<K, V> => {
const {
decodeURI = false,
onConflict = 'replace',
flatArraysOnAppend = false,
removeArrayDuplicatedValues = false,
} = options;
const newValue =
decodeURI && typeof value === 'string'
? decodeURIComponentSafe(value)
: value;
const hasKey = key in obj;
const current = obj[key as keyof T] as V | undefined;
if (hasKey) {
if (onConflict === 'ignore') return obj as T & Record<K, V>;
if (current !== newValue) {
if (onConflict === 'append' && Array.isArray(current)) {
let appended = [...current, newValue];
if (flatArraysOnAppend) appended = appended.flat();
if (removeArrayDuplicatedValues)
appended = Array.from(new Set(appended));
return { ...obj, [key]: appended } as T & Record<K, V>;
}
if (
onConflict === 'extend' &&
isPlainObject(current) &&
isPlainObject(newValue)
) {
return { ...obj, [key]: { ...current, ...newValue } } as T &
Record<K, V>;
}
if (onConflict === 'replace') {
return { ...obj, [key]: newValue } as T & Record<K, V>;
}
}
return obj as T & Record<K, V>;
}
return { ...obj, [key]: newValue } as T & Record<K, V>;
};
const decodeURIComponentSafe = (v: string): string => {
try {
return decodeURIComponent(v);
} catch {
return v;
}
};

Explanation:

  • decodeURI is useful when working with URL search parameters.
  • onConflict lets you control what happens if the key already exists. Options include:
    • 'replace' (default): overwrite the existing value.
    • 'append': merge values into an array.
    • 'extend': shallow-merge plain objects.
    • 'ignore': skip the update if the key exists.
  • flatArraysOnAppend is helpful when the new value is an array and you want to flatten the result. For example: if arr: [1] is updated with [2, 3], the result will be arr: [1, 2, 3].
  • removeArrayDuplicatedValues ensures that appended arrays don’t contain duplicate values.

 

You can find the code and useful JSDoc at this GitHub link.

Rating 5 of 5
#development#for_web#code_pool
Set key-value on JS Object! | The Latest Articles About Development And Architecture | Hosein Pouyanmehr