or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

dom-events.mddom-utilities.mdfocus-accessibility.mdfunction-utilities.mdindex.mdmath-utilities.mdobject-manipulation.mdreact-utilities.mdresponsive.mdtype-checking.md
tile.json

object-manipulation.mddocs/

Object Manipulation

Comprehensive utilities for manipulating objects including picking properties, omitting keys, merging objects, splitting objects, accessing nested properties, and walking object trees. These utilities are optimized for React prop handling, configuration objects, and data transformation pipelines.

Capabilities

Property Selection

Utilities for selecting specific properties from objects.

/**
 * Creates a new object with only the specified keys from the source object
 * @param object - Source object
 * @param keysToPick - Array of keys to include in the result
 * @returns New object containing only the specified keys
 */
function pick<T, K extends keyof T>(object: T, keysToPick: K[]): { [P in K]: T[P] };

/**
 * Creates a new object excluding the specified keys from the source object
 * @param object - Source object
 * @param keysToOmit - Array of keys to exclude from the result
 * @returns New object without the specified keys
 */
function omit<T, K extends keyof T>(object: T, keysToOmit: K[]): Omit<T, K>;

Usage Examples:

import { pick, omit } from "@chakra-ui/utils";

// Pick specific properties
const user = { name: "Alice", email: "alice@example.com", password: "secret", id: 1 };
const publicUser = pick(user, ["name", "email", "id"]);
// Result: { name: "Alice", email: "alice@example.com", id: 1 }

// Omit sensitive properties
const safeUser = omit(user, ["password"]);
// Result: { name: "Alice", email: "alice@example.com", id: 1 }

// React prop filtering
interface ButtonProps {
  children: React.ReactNode;
  onClick: () => void;
  className?: string;
  "data-testid"?: string;
}

function Button(props: ButtonProps) {
  const eventProps = pick(props, ["onClick"]);
  const domProps = omit(props, ["children", "onClick"]);
  
  return <button {...domProps} {...eventProps}>{props.children}</button>;
}

Object Splitting

Utilities for splitting objects into multiple parts.

/**
 * Splits an object into two parts: picked properties and remaining properties
 * @param object - Source object to split
 * @param keys - Array of keys to pick for the first object
 * @returns Tuple containing [picked object, remaining object]
 */
function split<T, K extends keyof T>(
  object: T, 
  keys: K[]
): [{ [P in K]: T[P] }, Omit<T, K>];

/**
 * Splits props into multiple objects based on key arrays
 * @param props - Source props object
 * @param keys - Arrays of keys to group into separate objects
 * @returns Array of objects corresponding to each key group
 */
function splitProps(props: Dict, ...keys: Key[]): Dict[];

Usage Examples:

import { split, splitProps } from "@chakra-ui/utils";

// Basic object splitting
const config = { 
  apiUrl: "https://api.example.com", 
  timeout: 5000, 
  retries: 3,
  debug: true,
  version: "v1"
};

const [networkConfig, otherConfig] = split(config, ["apiUrl", "timeout", "retries"]);
// networkConfig: { apiUrl: "https://api.example.com", timeout: 5000, retries: 3 }
// otherConfig: { debug: true, version: "v1" }

// React props splitting for complex components
function ComplexButton(props: any) {
  const [domProps, eventProps, styleProps] = splitProps(
    props,
    ["id", "className", "data-testid"], // DOM props
    ["onClick", "onFocus", "onBlur"],   // Event props
    ["color", "size", "variant"]        // Style props
  );
  
  return (
    <button 
      {...domProps} 
      {...eventProps}
      style={computeStyles(styleProps)}
    >
      {props.children}
    </button>
  );
}

Deep Property Access

Utilities for accessing nested object properties safely.

/**
 * Gets a nested property value from an object using a path string
 * @param obj - Source object to access
 * @param path - Property path (e.g., "user.profile.name" or "items[0].title")
 * @param fallback - Default value if property doesn't exist
 * @param index - Optional index for array access
 * @returns Property value or fallback
 */
function get(
  obj: Record<string, any>, 
  path: string | number, 
  fallback?: any, 
  index?: number
): any;

/**
 * Memoized version of the get function for better performance with repeated access
 * @param obj - Source object to access
 * @param path - Property path
 * @param fallback - Default value if property doesn't exist
 * @param index - Optional index for array access
 * @returns Property value or fallback
 */
function memoizedGet(
  obj: Record<string, any>, 
  path: string | number, 
  fallback?: any, 
  index?: number
): any;

Usage Examples:

import { get, memoizedGet } from "@chakra-ui/utils";

const data = {
  user: {
    profile: {
      name: "Alice",
      settings: {
        theme: "dark",
        notifications: ["email", "push"]
      }
    },
    posts: [
      { title: "Hello World", views: 100 },
      { title: "TypeScript Tips", views: 250 }
    ]
  }
};

// Deep property access
const userName = get(data, "user.profile.name");
// Result: "Alice"

const theme = get(data, "user.profile.settings.theme", "light");
// Result: "dark"

const firstNotification = get(data, "user.profile.settings.notifications[0]");
// Result: "email"

const nonExistent = get(data, "user.profile.bio", "No bio available");
// Result: "No bio available"

// Array access with index
const secondPostTitle = get(data, "user.posts", undefined, 1)?.title;
// Or using path notation
const secondPostViews = get(data, "user.posts[1].views");

// Memoized access for repeated calls
const memoGet = memoizedGet;
const cachedTheme = memoGet(data, "user.profile.settings.theme");

Object Merging

Deep merge utilities with custom merge strategies.

/**
 * Deep merge objects with custom merge function (re-exported from lodash.mergewith)
 * @param object - Target object
 * @param sources - Source objects to merge
 * @param customizer - Optional function to customize merge behavior
 * @returns Merged object
 */
function mergeWith(
  object: any,
  ...sources: any[]
): any;

Object Cleaning

Utilities for cleaning and transforming objects.

/**
 * Removes undefined properties from an object
 * @param object - Object to clean
 * @returns New object without undefined properties
 */
function compact<T extends Record<any, any>>(object: T): T;

/**
 * Object.assign that deletes existing keys before reassigning
 * @param target - Target object (will be modified)
 * @param sources - Source objects to assign from
 * @returns Modified target object
 */
function assignAfter(target: Record<string, any>, ...sources: any[]): Record<string, unknown>;

/**
 * Transforms an object by applying a function to all values
 * @param obj - Object to transform
 * @param fn - Function to apply to each value
 * @returns Transformed object
 */
function mapObject(obj: any, fn: (value: any) => any): any;

Usage Examples:

import { compact, assignAfter, mergeWith, mapObject } from "@chakra-ui/utils";

// Cleaning undefined properties
const props = {
  name: "Button",
  size: "md",
  variant: undefined,
  disabled: false,
  onClick: undefined
};

const cleanProps = compact(props);
// Result: { name: "Button", size: "md", disabled: false }

// Assign with cleanup
const target = { a: 1, b: 2, c: 3 };
const result = assignAfter(target, { b: 20, d: 4 });
// Result: { b: 20, d: 4 } (original keys a, c are deleted)

// Deep merging with custom logic
const defaults = { theme: { colors: { primary: "blue" } } };
const overrides = { theme: { colors: { secondary: "green" } } };

const merged = mergeWith(defaults, overrides, (objValue, srcValue) => {
  if (Array.isArray(objValue)) {
    return objValue.concat(srcValue);
  }
});

// Transform all values in an object
const config = { timeout: "5000", maxRetries: "3", debug: "true" };
const parsedConfig = mapObject(config, (value) => 
  value === "true" ? true : 
  value === "false" ? false : 
  /^\d+$/.test(value) ? parseInt(value) : value
);
// Result: { timeout: 5000, maxRetries: 3, debug: true }

Object Tree Walking

Utilities for recursively processing object structures.

/**
 * Recursively walks an object tree and applies a predicate function
 * @param target - Object to walk
 * @param predicate - Function to apply to each property
 * @param options - Walking options
 * @returns Transformed object
 */
function walkObject<T, K>(
  target: T,
  predicate: Predicate<K>,
  options?: WalkObjectOptions
): MappedObject<T, ReturnType<Predicate<K>>>;

interface WalkObjectOptions {
  stop?: WalkObjectStopFn;
}

type WalkObjectStopFn = (value: any, key: string) => boolean;
type Predicate<K> = (value: any, key: string, object: any) => K;
type MappedObject<T, U> = {
  [K in keyof T]: T[K] extends Record<string, any> ? MappedObject<T[K], U> : U;
};

Usage Examples:

import { walkObject } from "@chakra-ui/utils";

const theme = {
  colors: {
    primary: "#007bff",
    secondary: "#6c757d",
    nested: {
      light: "#f8f9fa",
      dark: "#343a40"
    }
  },
  spacing: {
    sm: "8px",
    md: "16px",
    lg: "24px"
  }
};

// Transform all string values to uppercase
const upperCaseTheme = walkObject(theme, (value, key) => {
  return typeof value === "string" ? value.toUpperCase() : value;
});

// Add prefix to all color values
const prefixedColors = walkObject(theme, (value, key, object) => {
  if (typeof value === "string" && value.startsWith("#")) {
    return `color-${value}`;
  }
  return value;
}, {
  stop: (value, key) => key === "spacing" // Skip spacing object
});