shelving/util/objectmodule

Core immutable helpers for reading and updating plain objects, plus utility types for mutable/readonly/partial transformations. These are the building blocks for safe state management — every mutating helper returns the original reference when nothing changed.

Things to know:

  • withProp() and withProps() preserve the object's prototype, so subclass instances survive updates intact.
  • Same-reference shortcut: if the new value is === to the existing value, the original object is returned without allocating.
  • omitProp() is an alias for omitProps() with a single key — they are the same function.
  • deleteProp() / deleteProps() and setProp() / setProps() mutate by reference; use the with* / omit* variants for immutable operations.
  • isObject() returns true for any non-null object including arrays and class instances. Use isPlainObject() when you need only {} shaped objects.

Usage

Type guards

ts
import { isObject, assertObject, isPlainObject, assertPlainObject } from "shelving/util";

isObject(null);           // false
isObject([]);             // true  (arrays are objects)
isPlainObject([]);        // false
isPlainObject(new Map()); // false
isPlainObject({ a: 1 }); // true

Immutable updates

ts
import { withProp, withProps, omitProp, omitProps, pickProps } from "shelving/util";

const obj = { a: 1, b: 2, c: 3 };

withProp(obj, "b", 99);         // { a: 1, b: 99, c: 3 }
withProp(obj, "b", 2);          // same ref — value unchanged

withProps(obj, { b: 99, c: 0 }); // { a: 1, b: 99, c: 0 }
withProps(obj, {});               // same ref

omitProp(obj, "b");             // { a: 1, c: 3 }
omitProps(obj, "a", "c");       // { b: 2 }

pickProps(obj, "a", "c");       // { a: 1, c: 3 }

Mutable updates (by reference)

ts
import { setProp, setProps, deleteProp, deleteProps } from "shelving/util";

const obj = { a: 1, b: 2, c: 3 };
setProp(obj, "a", 99);          // obj.a is now 99; returns 99
setProps(obj, { b: 10, c: 20 });
deleteProp(obj, "a");
deleteProps(obj, "b", "c");

Prop introspection

ts
import { isProp, assertProp, getProps, getKeys, getProp, fromProp } from "shelving/util";

isProp(obj, "a");               // true if "a" is an own key
getProps(obj);                  // entries as [key, value][] array
getKeys(obj);                   // keys as string[] array
getProp(obj, "a");              // obj.a — with type-safe return
fromProp("id", "abc");          // { id: "abc" }

Cloning

ts
import { cloneObject, cloneObjectWith, getObject } from "shelving/util";

cloneObject(obj);               // shallow copy, prototype preserved
cloneObjectWith(obj, "a", 99);  // same as withProp but always allocates

// Build an object from an iterable of [key, value] pairs.
getObject([["a", 1], ["b", 2]]); // { a: 1, b: 2 }

Utility types

ts
import type { Mutable, DeepPartial, DeepMutable, DeepReadonly, PickProps, OmitProps } from "shelving/util";

type W = DeepReadonly<{ a: { b: number } }>;  // recursively readonly
type X = DeepPartial<{ a: { b: number } }>;   // recursively optional
type Y = PickProps<User, string>;              // only string-valued props
type Z = OmitProps<User, string>;             // exclude string-valued props

Functions

Go

isObject()function

Is an unknown value an unknown object?

isObject(value: unknown): value is ImmutableObject
Go

assertObject()function

Assert that a value is an object.

assertObject(value: unknown): asserts value is ImmutableObject
Go

isPlainObject()function

Is an unknown value a plain object?

isPlainObject(value: unknown): value is ImmutableObject
Go

assertPlainObject()function

Assert that an unknown value is a plain object.

assertPlainObject(value: unknown): asserts value is ImmutableObject
Go

isProp()function

Is an unknown value the key for an own prop of an object.

isProp(obj: T, key: PropertyKey): key is keyof T
Go

assertProp()function

Assert that an unknown value is the key for an own prop of an object.

assertProp(obj: T, key: PropertyKey): asserts key is keyof T
Go

getObject()function

Turn a possible object into an object.

getObject(obj: PossibleObject<T>): T
Go

getProps()function

Get the props of an object as a set of entries.

getProps(obj: T): ImmutableArray<Prop<T>>
getProps(obj: T | Partial<T>): ImmutableArray<Prop<T>>
getProps(obj: T | Partial<T> | Iterable<Prop<T>>): Iterable<Prop<T>>
Go

getKeys()function

Get the keys of an object as an array.

getKeys(obj: T): ImmutableArray<Key<T>>
getKeys(obj: T | Partial<T>): ImmutableArray<Key<T>>
getKeys(obj: T | Partial<T> | Iterable<Key<T>>): Iterable<Key<T>>
Go

getProp()function

Extract the value of a named prop from an object.

getProp(obj: T, key: K): T[K]
Go

fromProp()function

Create an object from a single prop.

fromProp(key: K, value: V): { readonly [KK in K]: V }
Go

withProp()function

Set a prop on an object (immutably) and return a new object including that prop.

withProp(input: T, key: K, value: T[K]): T
Go

withProps()function

Set several props on an object (immutably) and return a new object including those props.

withProps(input: T, props: Partial<T>): T
withProps(input: T, props: T | Partial<T> | Iterable<Prop<T>>): T
Go

omitProps()function

Remove several props from an object (immutably) and return a new object without those props.

omitProps(input: T, ...keys: K[]): Omit<T, K>
Go

pickProps()function

Pick several props from an object and return a new object with only those props.

pickProps(obj: T, ...keys: K[]): Pick<T, K>
Go

setProp()function

Set a single named prop on an object (by reference) and return its value.

setProp(obj: T, key: K, value: T[K]): T[K]
Go

setProps()function

Set several named props on an object (by reference).

setProps(obj: T, entries: T | Partial<T> | Iterable<Prop<T>>): void
Go

deleteProps()function

Remove several key/value entries from an object (by reference).

deleteProps(obj: T, ...keys: Key<T>[]): void
Go

getPrototype()function

Get the prototype of an object instance.

getPrototype(obj: T): Partial<T> | null
Go

cloneObject()function

Shallow clone an object with the same prototype.

cloneObject(input: T): T
Go

cloneObjectWith()function

Shallow clone an object with a single changed value.

cloneObjectWith(input: T, key: K, value: T[K]): T
cloneObjectWith(input: T, key: K, value: V): T & { [KK in K]: V }

Types

Go

ImmutableObjecttype

Any readonly object.

{ readonly [KK in K]: T }
Go

MutableObjecttype

Any writable object.

{ [KK in K]: T }
Go

Proptype

Prop for an object, as a readonly key/value entry tuple.

readonly [keyof T, T[keyof T]]
Go

Keytype

Key for an object prop.

keyof T
Go

Valuetype

Value for an object prop.

T[keyof T]
Go

PossibleObjecttype

Something that can be converted to an object.

T | Iterable<Prop<T>>
Go

Mutabletype

Mutable type is the opposite of Readonly<T> helper type.

{ -readonly [K in keyof T]: T[K] }
Go

DeepPartialtype

Deep partial object: deeply convert an object to its partial version.

{ [K in keyof T]?: DeepPartial<T[K]> }
Go

DeepMutabletype

Deep mutable object: deeply convert an object to its mutable version.

{ -readonly [K in keyof T]: DeepMutable<T[K]> }
Go

DeepReadonlytype

Deep readonly object: deeply convert an object to its readonly version.

{ +readonly [K in keyof T]: DeepReadonly<T[K]> }
Go

PickPropstype

Pick only the properties of an object that match a type.

Pick<T, { [K in keyof T]: T[K] extends TT ? K : never }[keyof T]>
Go

OmitPropstype

Omit the properties of an object that match a type.

Omit<T, { [K in keyof T]: T[K] extends TT ? K : never }[keyof T]>

Constants

Go

omitPropconstant

Remove a prop from an object (immutably) and return a new object without that prop.

omitProp: <T, K extends Key<T>>(input: T, key: K) => Omit<T, K>
Go

deletePropconstant

Remove a key/value entry from an object (by reference).

deleteProp: <T extends MutableObject>(input: T, key: Key<T>) => void