or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-operations.mdasync-promise-utilities.mddata-utilities.mdfunction-utilities.mdindex.mdobject-operations.mdpath-operations.mdperformance-benchmarking.mdstring-utilities.mdvalidation-assertions.md
tile.json

object-operations.mddocs/

Object Operations

Core object manipulation functions including deep cloning, merging, and equality comparison with support for complex data types, circular references, and configurable behavior.

Capabilities

Clone

Creates a deep copy of any value, object, or array with configurable shallow copying and symbol handling.

/**
 * Clone any value, object, or array
 * @param obj - The value being cloned
 * @param options - Optional settings for cloning behavior
 * @returns A deep clone of obj
 */
function clone<T>(obj: T, options?: clone.Options): T;

namespace clone {
  interface Options {
    /** Clone the object's prototype. Defaults to true */
    readonly prototype?: boolean;
    /** Include symbol properties. Defaults to true */
    readonly symbols?: boolean;
    /** 
     * Shallow clone the specified keys. Can be:
     * - Array of dot-separated key paths to shallow copy
     * - Array of array-based key paths 
     * - true to shallow copy all properties
     */
    readonly shallow?: string[] | string[][] | boolean;
  }
}

Usage Examples:

import { clone } from "@hapi/hoek";

// Basic deep cloning
const original = {
  w: /^something$/ig,
  x: { a: [1, 2, 3], b: 123456, c: new Date() },
  y: 'y',
  z: new Date()
};

const copy = clone(original);
copy.x.b = 100;
console.log(original.x.b); // 123456 (unchanged)
console.log(copy.x.b);     // 100

// Shallow cloning specific keys
const shallowCopy = clone(original, { shallow: ['x'] });
shallowCopy.x.b = 999;
console.log(original.x.b); // 999 (changed - x was shallow copied)

Merge

Merges all properties of source into target (destructive operation) with configurable null handling and array merging.

/**
 * Merge all the properties of source into target
 * @param target - The object being modified
 * @param source - The object used to copy properties from
 * @param options - Optional settings for merge behavior
 * @returns The target object with merged properties
 */
function merge<T1 extends object, T2 extends object>(target: T1, source: T2, options?: merge.Options): T1 & T2;

namespace merge {
  interface Options {
    /** When true, null value from source overrides existing value in target. Defaults to true */
    readonly nullOverride?: boolean;
    /** When true, array value from source is merged with existing value in target. Defaults to true */
    readonly mergeArrays?: boolean;
    /** Compare symbol properties. Defaults to undefined */
    readonly symbols?: boolean;
  }
}

Usage Examples:

import { merge } from "@hapi/hoek";

// Basic object merging
const target = { a: 1, b: 2 };
const source = { a: 0, c: 5 };
merge(target, source); // target becomes { a: 0, b: 2, c: 5 }

// Null value handling
const target2 = { a: 1, b: 2 };
const source2 = { a: null, c: 5 };
merge(target2, source2); // { a: null, b: 2, c: 5 }
merge(target2, source2, { nullOverride: false }); // { a: 1, b: 2, c: 5 }

// Array merging
const targetArray = [1, 2, 3];
const sourceArray = [4, 5];
merge(targetArray, sourceArray); // [1, 2, 3, 4, 5]
merge(targetArray, sourceArray, { mergeArrays: false }); // [4, 5]

Apply to Defaults

Applies source to a copy of defaults (non-destructive) creating a new object with merged properties.

/**
 * Apply source to a copy of the defaults
 * @param defaults - An object with the default values to use if options does not contain the same keys
 * @param source - The source used to override the defaults
 * @param options - Optional settings for application behavior
 * @returns A copy of defaults with source keys overriding any conflicts, or null if source is falsy
 */
function applyToDefaults<T extends object>(defaults: Partial<T>, source: Partial<T> | boolean | null, options?: applyToDefaults.Options): Partial<T> | null;

namespace applyToDefaults {
  interface Options {
    /** When true, null value from source overrides existing value in target. Defaults to false */
    readonly nullOverride?: boolean;
    /** Shallow clone the specified keys. Can be array of dot-separated or array-based key paths */
    readonly shallow?: string[] | string[][];
  }
}

Usage Examples:

import { applyToDefaults } from "@hapi/hoek";

// Basic usage
const defaults = { host: "localhost", port: 8000 };
const source = { port: 8080 };
const config = applyToDefaults(defaults, source); 
// Result: { host: "localhost", port: 8080 }

// Null value handling
const defaults2 = { host: "localhost", port: 8000 };
const source2 = { host: null, port: 8080 };
const config2 = applyToDefaults(defaults2, source2, { nullOverride: true });
// Result: { host: null, port: 8080 }

// Shallow copying specific paths
const defaults3 = {
  db: { server: { host: "localhost", port: 8000 }, name: 'example' }
};
const source3 = { db: { server: { port: 8080 } } };
const config3 = applyToDefaults(defaults3, source3, { shallow: ['db.server'] });
// Result: { db: { server: { port: 8080 }, name: 'example' } }

Deep Equal

Performs deep comparison of two values including support for circular dependencies, prototype comparison, and enumerable properties.

/**
 * Performs a deep comparison of the two values including support for circular dependencies, prototype, and enumerable properties
 * @param obj - The value being compared
 * @param ref - The reference value used for comparison
 * @param options - Optional settings for comparison behavior
 * @returns true when the two values are equal, otherwise false
 */
function deepEqual(obj: any, ref: any, options?: deepEqual.Options): boolean;

namespace deepEqual {
  interface Options {
    /** Compare functions with different references by comparing their internal code and properties. Defaults to false */
    readonly deepFunction?: boolean;
    /** Allow partial match. Defaults to false */
    readonly part?: boolean;
    /** Compare the objects' prototypes. Defaults to true */
    readonly prototype?: boolean;
    /** List of object keys to ignore different values of. Defaults to null */
    readonly skip?: (string | symbol)[];
    /** Compare symbol properties. Defaults to true */
    readonly symbols?: boolean;
  }
}

Usage Examples:

import { deepEqual } from "@hapi/hoek";

// Basic deep comparison
const obj1 = { a: [1, 2], b: 'string', c: { d: true } };
const obj2 = { a: [1, 2], b: 'string', c: { d: true } };
deepEqual(obj1, obj2); // true

// Prototype comparison
deepEqual(Object.create(null), {}, { prototype: false }); // true
deepEqual(Object.create(null), {}); // false

// Partial matching
const partial = { a: 1 };
const full = { a: 1, b: 2, c: 3 };
deepEqual(partial, full, { part: true }); // true

// Skip specific keys
deepEqual(
  { a: 1, b: 2, timestamp: 123 },
  { a: 1, b: 2, timestamp: 456 },
  { skip: ['timestamp'] }
); // true