Core Utilities

Deep Utilities

Advanced utilities for deep manipulation of objects and nested types in TypeScript. These types allow you to merge, transform, filter, select, omit, and modify properties at any depth in a type-safe and expressive way.

Deep Utilities

Advanced utilities for deep manipulation of objects and nested types in TypeScript. These types allow you to merge, transform, filter, select, omit, and modify properties at any depth in a type-safe and expressive way.

Installation

npm i -D @halvaradop/ts-utility-types

Usage

import type { , ,  } from "@halvaradop/ts-utility-types/deep" 
import type * as  from "@halvaradop/ts-utility-types/deep"


type  = .
  • DeepFilter
  • DeepGet
  • DeepKeys
  • DeepMerge
  • DeepMergeAll
  • DeepMutable
  • DeepNonNullable
  • DeepNonNullish
  • DeepNullable
  • DeepOmit
  • DeepPartial
  • DeepPick
  • DeepReadonly
  • DeepReplace
  • DeepRequired
  • DeepSet
  • DeepTruncate
  • DeepUnion

DeepMerge<Obj1, Obj2, ByUnion, PriorityObject>

Recursively merges two objects. If a property exists in both, the one from Obj1 takes priority (unless otherwise specified). You can merge as a union (ByUnion) or prioritize objects (PriorityObject).

ArgumentTypeDescription
Obj1objectThe first object to merge.
Obj2objectThe second object to merge.
ByUnionboolean (default false)If true, conflicting properties are combined as unions.
PriorityObjectboolean (default true)If true, Obj1 properties take priority over Obj2 properties.

Related: DeepMergeAll, DeepUnion

Performance Note

Deep utilities work with recursive types and may have performance implications with deeply nested structures. Most operations are limited to reasonable depths (typically 10-20 levels).

import type {  } from "@halvaradop/ts-utility-types/deep"

interface Config {
  : {
    : number
  }
  : {
    : boolean
  }
}

interface UserConfig {
  : {
    : number
  }
  : {
    : boolean
  }
}

type AppConfig = <Config, UserConfig>
type AppConfig = {
    api: {
        timeout: number;
        retries: number;
    };
    features: {
        darkMode: boolean;
        analytics: boolean;
    };
}
const : = { : { : 5000, : 3, }, : { : true, : false, }, }

DeepUnion<Obj1, Obj2>

ArgumentTypeDescription
Obj1objectThe first object to merge.
Obj2objectThe second object to merge.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface BaseController {
  : string
  : string[]
}

interface ConfigBase {
  : string[]
  : <{ : string; : string }>
}

type Union = <BaseController, ConfigBase>
type Union = {
    baseUrl: string | string[];
    routes: string[] | {
        url: string;
        name: string;
    }[];
}

DeepMergeAll<Array, ByUnion, PriorityObject>

ArgumentTypeDescription
Arrayunknown[]The tuple of object types to merge.
ByUnionboolean (default false)If true, conflicting properties are combined as unions.
PriorityObjectboolean (default true)If true, earlier objects take priority over later ones.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface Foo {
  : string
}

interface Bar {
  : string
}

interface FooBar {
  : number
  : boolean
  : string
}

type Merge = <[Foo, Bar, FooBar], true>
type Merge = {
    foo: string;
    bar: string;
    foobar: string;
}

DeepMutable<Obj>

ArgumentTypeDescription
ObjobjectThe object to make mutable deeply.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface Foo {
  readonly : { readonly : { readonly : number } }
}

type NonReadonlyFoo = <Foo>
type NonReadonlyFoo = {
    foo: {
        bar: {
            foobar: number;
        };
    };
}

DeepReadonly<Obj>

ArgumentTypeDescription
ObjobjectThe object to make deeply readonly.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type ReadonlyUser = <User>
type ReadonlyUser = {
    readonly name: string;
    readonly address: {
        readonly street: string;
        readonly avenue: string;
    };
}

DeepKeys<Obj, Depth>

ArgumentTypeDescription
ObjobjectThe object to extract keys from.
Depthnumber (default 6)The maximum depth to traverse for keys.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type UserKeys = <User>
type UserKeys = "name" | "address" | "address.street" | "address.avenue"

DeepOmit<Obj, Path>

ArgumentTypeDescription
ObjobjectThe object to omit a property from.
PathstringThe dot-separated path to omit.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type WithoutStreet = <User, "address.street">
type WithoutStreet = {
    name: string;
    address: {
        avenue: string;
    };
}

DeepGet<Obj, Path>

ArgumentTypeDescription
ObjobjectThe object to get a value from.
PathstringThe dot-separated path to retrieve.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type UserName = <User, "name">
type UserName = string
type UserStreet = <User, "address.street">
type UserStreet = string

DeepTruncate<Obj, Depth>

ArgumentTypeDescription
ObjobjectThe object to truncate.
DepthnumberThe depth at which to truncate.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface Foo {
  : string
  : number
  : {
    : boolean
    : string
    : {
      : number
    }
  }
}

type TruncatedFoo = <Foo, 1>
type TruncatedFoo = {
    foo: string;
    bar: number;
    foobar: {};
}

DeepPartial<Obj>

ArgumentTypeDescription
ObjobjectThe object to make deeply optional.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type UserOptional = <User>
type UserOptional = {
    name?: string | undefined;
    address?: {
        street?: string | undefined;
        avenue?: string | undefined;
    } | undefined;
}

DeepRequired<Obj>

ArgumentTypeDescription
ObjobjectThe object to make deeply required.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  ?: string
  ?: {
    ?: string
    ?: string
  }
}

type UserRequired = <User>
type UserRequired = {
    name: string;
    address: {
        street: string;
        avenue: string;
    };
}

DeepPick<Obj, Path>

ArgumentTypeDescription
ObjobjectThe object to pick a property from.
PathstringThe dot-separated path to pick.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type UserPick = <User, "address.street">
type UserPick = {
    address: {
        street: string;
    };
}

DeepNullable<Obj>

ArgumentTypeDescription
ObjobjectThe object to make deeply nullable.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type UserNullable = <User>
type UserNullable = {
    name: string | null;
    address: {
        street: string | null;
        avenue: string | null;
    } | null;
}

DeepNonNullable<Obj>

ArgumentTypeDescription
ObjobjectThe object to make deeply non-nullable.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string | null
  : {
    : string | null
    : string | null
  } | null
}

type UserNonNullable = <User>
type UserNonNullable = {
    name: string;
    address: {
        street: string;
        avenue: string;
    };
}

DeepFilter<Obj, Predicate>

ArgumentTypeDescription
ObjobjectThe object to filter.
PredicateunknownThe type to filter properties by.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : number
  : { : string; : string }
}

type Filtered = <User, string>
type Filtered = {
    name: string;
}

DeepReplace<Obj, From, To>

ArgumentTypeDescription
ObjobjectThe object to replace types in.
FromunknownThe type to replace.
TounknownThe type to use as a replacement.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : number
  : { : string; : string }
}

type Replaced = <User, string, number>
type Replaced = {
    name: number;
    age: number;
    address: {
        street: number;
        avenue: number;
    };
}

DeepSet<Obj, Path, Value>

ArgumentTypeDescription
ObjobjectThe object to set a value in.
PathstringThe dot-separated path to set.
ValueunknownThe value type to set at the path.
import type {  } from "@halvaradop/ts-utility-types/deep"

interface User {
  : string
  : { : string; : string }
}

type Updated = <User, "address.street", number>
type Updated = {
    name: string;
    address: {
        street: number;
        avenue: string;
    };
}