Skip to content

DeepSet

Produces the type of T after replacing the value at Path with V.

When a key in Path is absent from the corresponding level of T, that level (and everything below it) is added as a new field instead of resolving to never — mirroring how set() creates intermediate objects at runtime.

Available since v3.0.0

import type { DeepSet } from '@helpers4/type';
type DeepSet<T, Path extends readonly PropertyKey[], V> =
  Path extends readonly []
    ? V
    : Path extends readonly [infer K extends PropertyKey, ...infer Rest extends readonly PropertyKey[]]
      ? T extends object
        ? K extends keyof T
          ? { [P in keyof T]: P extends K ? DeepSet<T[K], Rest, V> : T[P] }
          : T & Record<K, BuildPath<Rest, V>>
        : BuildPath<Path, V>
      : never
type Obj = { a: { b: number; c: string } };

DeepSet<Obj, ['a', 'b'], string>
// => { a: { b: string; c: string } }

DeepSet<Obj, ['a', 'x'], boolean>
// => { a: { b: number; c: string } & { x: boolean } }

View source on GitHub