CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ts-essentials

All essential TypeScript types in one place providing 70+ utility types and helper functions.

Pending
Overview
Eval results
Files

deep-wrapper-types.mddocs/

Deep Wrapper Types

Recursive type transformations that apply operations to nested object structures at any depth. These types work recursively through all levels of object nesting.

Capabilities

Buildable

Constructs a type by combining DeepPartial and DeepWritable, meaning all properties from type Type are recursively set as non-readonly and optional.

type Buildable<Type> = DeepWritable<DeepPartial<Type>>;

Usage Example:

import type { Buildable } from "ts-essentials";

type User = {
  readonly id: number;
  readonly profile: {
    readonly name: string;
    readonly settings: {
      readonly theme: string;
      readonly notifications: boolean;
    };
  };
};

type UserBuilder = Buildable<User>;
// Result: All properties optional and writable recursively
// {
//   id?: number;
//   profile?: {
//     name?: string;
//     settings?: {
//       theme?: string;
//       notifications?: boolean;
//     };
//   };
// }

const builder: UserBuilder = {}; // Valid - all optional
builder.id = 1; // Valid - all writable

DeepMarkOptional

Constructs a type by picking all properties from type Type where properties by paths KeyPathUnion are set as optional recursively.

type DeepMarkOptional<Type, KeyPathUnion extends Paths<Type>> = /* complex recursive type */;

Usage Example:

import type { DeepMarkOptional } from "ts-essentials";

type User = {
  id: number;
  profile: {
    name: string;
    settings: {
      theme: string;
      lang: string;
    };
  };
};

type OptionalTheme = DeepMarkOptional<User, "profile.settings.theme">;
// Makes the nested theme property optional while keeping everything else required

DeepMarkRequired

Constructs a type by picking all properties from type Type where properties by paths KeyPathUnion are set as required recursively.

type DeepMarkRequired<Type, KeyPathUnion extends Paths<Type>> = /* complex recursive type */;

Usage Example:

import type { DeepMarkRequired } from "ts-essentials";

type PartialUser = {
  id?: number;
  profile?: {
    name?: string;
    settings?: {
      theme?: string;
      lang?: string;
    };
  };
};

type RequiredName = DeepMarkRequired<PartialUser, "profile.name">;
// Makes the nested name property required while keeping others optional

DeepNonNullable

Constructs a type by picking all properties from type Type recursively and exclude null and undefined property values from all of them.

type DeepNonNullable<Type> = Type extends Function
  ? Type
  : Type extends any[]
    ? DeepNonNullableArray<Type>
    : Type extends ReadonlyArray<any>
      ? DeepNonNullableReadonlyArray<Type>
      : DeepNonNullableObject<Type>;

type DeepNonNullableObject<Type> = {
  [Key in keyof Type]-?: DeepNonNullable<NonNullable<Type[Key]>>;
};

Usage Example:

import type { DeepNonNullable } from "ts-essentials";

type User = {
  id: number | null;
  profile: {
    name: string | undefined;
    avatar: string | null;
    settings?: {
      theme: string | null;
    };
  } | null;
};

type CleanUser = DeepNonNullable<User>;
// Result: All null and undefined removed recursively
// {
//   id: number;
//   profile: {
//     name: string;
//     avatar: string;
//     settings: {
//       theme: string;
//     };
//   };
// }

DeepNullable

Constructs a type by picking all properties from type Type recursively and include null property values for all of them.

type DeepNullable<Type> = Type extends Function
  ? Type
  : Type extends any[]
    ? DeepNullableArray<Type>
    : Type extends ReadonlyArray<any>
      ? DeepNullableReadonlyArray<Type>
      : DeepNullableObject<Type>;

type DeepNullableObject<Type> = {
  [Key in keyof Type]: DeepNullable<Type[Key]> | null;
};

DeepOmit

Constructs a type by picking all properties from type Type and removing properties which values are never or true in type Filter.

type DeepOmit<Type, Filter> = Type extends any[]
  ? Type
  : Type extends ReadonlyArray<any>
    ? Type
    : DeepOmitObject<Type, Filter>;

Usage Example:

import type { DeepOmit } from "ts-essentials";

type User = {
  id: number;
  password: string;
  profile: {
    name: string;
    email: string;
    secret: string;
  };
};

type OmitFilter = {
  password: true;
  profile: {
    secret: true;
  };
};

type PublicUser = DeepOmit<User, OmitFilter>;
// Result: { id: number; profile: { name: string; email: string; } }

DeepPartial

Constructs a type by picking all properties from type Type recursively and setting them as optional.

type DeepPartial<Type> = Type extends Function
  ? Type
  : Type extends Array<infer U>
    ? Array<DeepPartial<U>>
    : Type extends ReadonlyArray<infer U>
      ? ReadonlyArray<DeepPartial<U>>
      : { [K in keyof Type]?: DeepPartial<Type[K]> };

Usage Example:

import type { DeepPartial } from "ts-essentials";

type User = {
  id: number;
  profile: {
    name: string;
    settings: {
      theme: string;
      notifications: boolean;
    };
  };
};

type PartialUser = DeepPartial<User>;
// Result: All properties optional recursively
// {
//   id?: number;
//   profile?: {
//     name?: string;
//     settings?: {
//       theme?: string;
//       notifications?: boolean;
//     };
//   };
// }

const update: PartialUser = {
  profile: {
    settings: {
      theme: "dark"
      // notifications can be omitted
    }
    // name can be omitted
  }
  // id can be omitted
};

DeepPick

Constructs a type by picking set of properties, which have property values never or true in type Filter, from type Type.

type DeepPick<Type, Filter> = Type extends any[]
  ? Type
  : Type extends ReadonlyArray<any>
    ? Type
    : DeepPickObject<Type, Filter>;

Usage Example:

import type { DeepPick } from "ts-essentials";

type User = {
  id: number;
  password: string;
  profile: {
    name: string;
    email: string;
    avatar: string;
  };
};

type PickFilter = {
  id: true;
  profile: {
    name: true;
    email: true;
  };
};

type PublicUserInfo = DeepPick<User, PickFilter>;
// Result: { id: number; profile: { name: string; email: string; } }

DeepReadonly

Constructs a type by picking all properties from type Type recursively and setting readonly modifier.

type DeepReadonly<Type> = Type extends Function
  ? Type
  : Type extends Array<infer U>
    ? ReadonlyArray<DeepReadonly<U>>
    : { readonly [K in keyof Type]: DeepReadonly<Type[K]> };

Usage Example:

import type { DeepReadonly } from "ts-essentials";

type User = {
  id: number;
  profile: {
    name: string;
    settings: {
      theme: string;
    };
  };
};

type ImmutableUser = DeepReadonly<User>;
// Result: All properties readonly recursively

const user: ImmutableUser = {
  id: 1,
  profile: {
    name: "Alice",
    settings: {
      theme: "dark"
    }
  }
};

// user.id = 2; // Error: readonly
// user.profile.name = "Bob"; // Error: readonly
// user.profile.settings.theme = "light"; // Error: readonly

DeepRequired

Constructs a type by picking all properties from type Type recursively and setting as required.

type DeepRequired<Type> = Type extends Function
  ? Type
  : Type extends Array<infer U>
    ? Array<DeepRequired<NonNullable<U>>>
    : Type extends ReadonlyArray<infer U>
      ? ReadonlyArray<DeepRequired<NonNullable<U>>>
      : { [K in keyof Type]-?: DeepRequired<NonNullable<Type[K]>> };

Usage Example:

import type { DeepRequired } from "ts-essentials";

type PartialUser = {
  id?: number;
  profile?: {
    name?: string;
    settings?: {
      theme?: string;
    };
  };
};

type CompleteUser = DeepRequired<PartialUser>;
// Result: All properties required recursively
// {
//   id: number;
//   profile: {
//     name: string;
//     settings: {
//       theme: string;
//     };
//   };
// }

DeepUndefinable

Constructs a type by picking all properties from type Type recursively and include undefined property values for all of them.

type DeepUndefinable<Type> = Type extends Function
  ? Type
  : Type extends any[]
    ? DeepUndefinableArray<Type>
    : Type extends ReadonlyArray<any>
      ? DeepUndefinableReadonlyArray<Type>
      : DeepUndefinableObject<Type>;

type DeepUndefinableObject<Type> = {
  [Key in keyof Type]: DeepUndefinable<Type[Key]> | undefined;
};

DeepWritable

Constructs a type by picking all properties from type Type recursively and removing readonly modifier.

type DeepWritable<Type> = Type extends Function
  ? Type
  : Type extends ReadonlyArray<infer U>
    ? DeepWritable<U>[]
    : { -readonly [K in keyof Type]: DeepWritable<Type[K]> };

Usage Example:

import type { DeepWritable } from "ts-essentials";

type ImmutableUser = {
  readonly id: number;
  readonly profile: {
    readonly name: string;
    readonly settings: {
      readonly theme: string;
    };
  };
};

type MutableUser = DeepWritable<ImmutableUser>;
// Result: All readonly modifiers removed recursively

const user: MutableUser = {
  id: 1,
  profile: {
    name: "Alice",
    settings: {
      theme: "dark"
    }
  }
};

user.id = 2; // OK
user.profile.name = "Bob"; // OK
user.profile.settings.theme = "light"; // OK

StrictDeepOmit

Constructs a type by picking all properties from type Type and removing properties which values are never or true in type Filter. The type Filter is validated against a structure of Type.

type StrictDeepOmit<Type, Filter> = DeepOmit<Type, Filter>;

StrictDeepPick

Constructs a type by picking set of properties, which have property values never or true in type Filter, from type Type. The type Filter is validated against a structure of Type.

type StrictDeepPick<Type, Filter> = DeepPick<Type, Filter>;

Install with Tessl CLI

npx tessl i tessl/npm-ts-essentials

docs

array-tuple-types.md

basic-types.md

change-case-types.md

deep-wrapper-types.md

function-types.md

index.md

key-types.md

mark-wrapper-types.md

type-checkers.md

utility-functions.md

utility-types.md

tile.json