Skip to content

Objects & random

js
import { 
deepmerge
,
random
,
randomInt
,
randomItem
} from '@studiometa/js-toolkit/utils';

Merging

deepmerge

ts
deepmerge(...layers: Record<string, unknown>[]): Record<string, unknown>
js
import { 
deepmerge
} from '@studiometa/js-toolkit/utils';
deepmerge
({
tween
: {
ease
: 'linear',
duration
: 300 } }, {
tween
: {
ease
: 'ease-out' } });
// { tween: { ease: 'ease-out', duration: 300 } }

Later layers win, at every depth. Plain objects merge; anything else — an array, a Date, an element, a class instance — replaces.

That last rule is the one worth knowing: an array is a value, not a structure to merge, because merging two arrays by index is almost never what a caller meant.

It ships for the consumer, not for core

A utility is judged by consumer need, not by whether core calls it. Layering a default config under an author's config is the case every component author meets, and getting the array rule wrong is exactly how a hand-rolled merge misbehaves.

Random

js
import { 
random
,
randomInt
,
randomItem
} from '@studiometa/js-toolkit/utils';
random
(10); // 0 → 10
random
(5, 10); // 5 → 10
randomInt
(10); // an integer, 0 → 10
randomItem
(['a', 'b', 'c']);

One argument is a maximum; two are a range.

random

ts
random(a: number, b?: number): number

A float in the range.

randomInt

ts
randomInt(a: number, b?: number): number

An integer in the range, bounds inclusive.

randomItem

ts
randomItem<T>(items: readonly T[]): T | undefined
randomItem(items: string): string | undefined

One item from an array, or one character from a string.

The return includes undefined because an empty input has no item to give — and a signature that pretended otherwise would put the bug three lines later.

MIT Licensed