CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ts-toolbelt

TypeScript's largest utility library providing 200+ type utilities for advanced type manipulation.

Pending
Overview
Eval results
Files

object.mddocs/

Object Module

Extensive object manipulation utilities providing property access, transformation operations, and deep path-based modifications. The second largest module with 55+ type utilities.

Capabilities

Property Access and Query

Access properties, check existence, and extract keys and values.

/**
 * Access property at key K in object O
 * @param O - Object type to access
 * @param K - Key to access
 * @returns Property type at key K
 */
type At<O extends Object, K extends keyof O> = O[K];

/**
 * Check if object O has property K
 * @param O - Object type to check
 * @param K - Key to check for
 * @returns 1 if property exists, 0 otherwise
 */
type Has<O extends Object, K extends Key> = K extends keyof O ? 1 : 0;

/**
 * Extract all keys from object O
 * @param O - Object type to extract keys from
 * @returns Union of all keys
 */
type Keys<O extends Object> = keyof O;

/**
 * Extract known keys (non-index signature) from object O
 * @param O - Object type to extract known keys from
 * @returns Union of known keys
 */
type KnownKeys<O extends Object> = keyof O;

/**
 * Extract all values from object O
 * @param O - Object type to extract values from
 * @returns Union of all property values
 */
type Values<O extends Object> = O[keyof O];

/**
 * Generate all possible paths to properties in object O
 * @param O - Object type to generate paths for
 * @returns Union of all property paths
 */
type Paths<O extends Object> = PathsImpl<O>;

Usage Examples:

import { O } from "ts-toolbelt";

type User = { 
  name: string; 
  age: number; 
  address: { street: string; city: string }; 
};

type Name = O.At<User, "name">; // string
type HasEmail = O.Has<User, "email">; // 0
type HasName = O.Has<User, "name">; // 1
type UserKeys = O.Keys<User>; // "name" | "age" | "address"
type UserValues = O.Values<User>; // string | number | { street: string; city: string }
type UserPaths = O.Paths<User>; // "name" | "age" | "address" | "address.street" | "address.city"

Advanced Key Operations

Additional key-based operations for filtering, selecting, and working with object keys.

/**
 * Get the keys of O which fields match M
 * @param O - Object to extract from
 * @param M - Type to select fields
 * @param match - Precision mode for matching
 * @returns Union of keys whose values match M
 */
type SelectKeys<O extends Object, M extends any, match extends Match = 'default'> = SelectKeysImpl<O, M, match>;

/**
 * Filter out the keys of O which fields match M
 * @param O - Object to remove from
 * @param M - Type to select fields
 * @param match - Precision mode for matching
 * @returns Union of keys whose values don't match M
 */
type FilterKeys<O extends Object, M extends any, match extends Match = 'default'> = FilterKeysImpl<O, M, match>;

/**
 * Get the intersecting keys of O & O1
 * @param O - Object to check similarities with
 * @param O1 - Object to check similarities against
 * @param match - Precision mode for matching
 * @returns Union of common keys
 */
type IntersectKeys<O extends Object, O1 extends Object, match extends Match = 'default'> = IntersectKeysImpl<O, O1, match>;

/**
 * Exclude the keys of O1 out of the keys of O
 * @param O - Object to remove keys from
 * @param O1 - Object whose keys to remove
 * @param match - Precision mode for matching
 * @returns Union of keys in O but not in O1
 */
type ExcludeKeys<O extends Object, O1 extends Object, match extends Match = 'default'> = ExcludeKeysImpl<O, O1, match>;

Nullable Key Operations

Operations for working with nullable, non-nullable, and undefinable keys.

/**
 * Get the keys of O that are non-nullable
 * @param O - Object to extract from
 * @returns Union of non-nullable keys
 */
type NonNullableKeys<O extends Object> = NonNullableKeysImpl<O>;

/**
 * Get the keys of O that are nullable
 * @param O - Object to extract from
 * @returns Union of nullable keys
 */
type NullableKeys<O extends Object> = NullableKeysImpl<O>;

/**
 * Get the keys of O that are undefinable
 * @param O - Object to extract from
 * @returns Union of undefinable keys
 */
type UndefinableKeys<O extends Object> = UndefinableKeysImpl<O>;

Core Transformations

Essential object transformation operations for creating new object types.

/**
 * Pick specific properties from object O
 * @param O - Object type to pick from
 * @param K - Keys to pick
 * @returns New object with only picked properties
 */
type Pick<O extends Object, K extends keyof O> = { [P in K]: O[P] } & {};

/**
 * Omit specific properties from object O
 * @param O - Object type to omit from
 * @param K - Keys to omit
 * @returns New object without omitted properties
 */
type Omit<O extends Object, K extends keyof O> = Pick<O, Exclude<keyof O, K>>;

/**
 * Merge two objects with optional depth control
 * @param O1 - First object to merge
 * @param O2 - Second object to merge
 * @param depth - Merge depth: 'flat' or 'deep'
 * @returns Merged object type
 */
type Merge<O1 extends Object, O2 extends Object, depth extends 'flat' | 'deep' = 'flat'> = 
  depth extends 'flat' ? O1 & O2 : MergeDeep<O1, O2>;

/**
 * Merge multiple objects into one
 * @param Os - Array of object types to merge
 * @returns Single merged object type
 */
type MergeAll<Os extends readonly Object[]> = MergeAllImpl<Os>;

/**
 * Assign properties from source to target object
 * @param O - Target object type
 * @param O1 - Source object type
 * @returns Object with assigned properties
 */
type Assign<O extends Object, O1 extends Object> = O & O1;

Usage Examples:

import { O } from "ts-toolbelt";

type User = { name: string; age: number; email: string; active: boolean };

type BasicUser = O.Pick<User, "name" | "age">; // { name: string; age: number }
type PublicUser = O.Omit<User, "email">; // { name: string; age: number; active: boolean }

type Address = { street: string; city: string };
type UserWithAddress = O.Merge<User, Address>; 
// { name: string; age: number; email: string; active: boolean; street: string; city: string }

// Deep merge example
type UserProfile = { user: { name: string } };
type UserDetails = { user: { age: number } };
type FullProfile = O.Merge<UserProfile, UserDetails, 'deep'>; 
// { user: { name: string; age: number } }

type MultiMerge = O.MergeAll<[User, Address, { score: number }]>;
// { name: string; age: number; email: string; active: boolean; street: string; city: string; score: number }

Object Operations

Advanced object operations including exclusion, intersection, and validation.

/**
 * Exclude the fields of O1 out of O
 * @param O - Object to remove from
 * @param O1 - Object whose fields to remove
 * @param match - Precision mode for matching
 * @returns Object with O1 fields removed
 */
type Exclude<O extends Object, O1 extends Object, match extends Match = 'default'> = Pick<O, ExcludeKeys<O, O1, match>>;

/**
 * Get the intersecting fields of O & O1
 * @param O - Object to check similarities with
 * @param O1 - Object to check similarities against
 * @param match - Precision mode for matching
 * @returns Object with only common fields
 */
type Intersect<O extends Object, O1 extends Object, match extends Match = 'default'> = Pick<O, IntersectKeys<O, O1, match>>;

/**
 * Check whether O has fields that match M
 * @param O - Object to be inspected
 * @param M - Type to check field type
 * @param match - Precision mode for matching
 * @returns 1 if match found, 0 otherwise
 */
type Includes<O extends Object, M extends any, match extends Match = 'default'> = [SelectKeys<O, M, match>] extends [never] ? 0 : 1;

/**
 * Swap the keys and values of an object
 * @param O - Object to invert
 * @returns Object with keys and values swapped
 */
type Invert<O extends Record<keyof O, Key>> = InvertImpl<O>;

/**
 * Make the fields of O union the ones of O1
 * @param O - Object to union from
 * @param O1 - Object to union with
 * @param K - Keys to choose fields
 * @returns Object with unionized field types
 */
type Unionize<O extends Object, O1 extends Object, K extends Key = Key> = {
    [P in keyof O]: P extends K ? O[P] | At<O1, P> : O[P];
} & {};

Constraint Operations

Operations for applying constraints and requirements to object types.

/**
 * Make that at least one of the keys K are required in O at a time
 * @param O - Object to make required
 * @param K - Keys to choose fields
 * @returns Object union with at least one required key
 */
type AtLeast<O extends object, K extends Key = Keys<O>> = O extends unknown ? _AtLeast<O, K> : never;

/**
 * Split O into a union where none of the K keys are present together
 * @param O - Object to split
 * @param K - Keys to split with
 * @param strict - Force excess property checks
 * @returns Object union with mutually exclusive keys
 */
type Either<O extends object, K extends Key, strict extends Boolean = 1> = O extends unknown ? _Either<O, K, strict> : never;

Transformation Operations

Operations for transforming objects into other types.

/**
 * Transform an object into a list
 * @param O - Object to transform
 * @returns List representation of object
 */
type ListOf<O extends Object> = ListOfImpl<O>;

/**
 * Transform an object into a union of its values
 * @param O - Object to transform
 * @returns Union of all property values
 */
type UnionOf<O extends Object> = UnionOfImpl<O>;

/**
 * Merge a list of objects into O
 * @param O - Object to start with
 * @param Os - List of objects to merge
 * @param depth - Merge depth ('flat' or 'deep')
 * @param ignore - Types not to merge
 * @param fill - Types to be replaced
 * @returns Merged object
 */
type MergeAll<O extends Object, Os extends List<Object>, depth extends Depth = 'flat', ignore extends Object = BuiltIn, fill extends any = undefined> = MergeAllImpl<O, Os, depth, ignore, fill>;

/**
 * Patch a list of objects into O
 * @param O - Object to start with
 * @param Os - List of objects to patch
 * @param depth - Patch depth ('flat' or 'deep')
 * @param ignore - Types not to merge
 * @param fill - Types to be replaced
 * @returns Patched object
 */
type PatchAll<O extends Object, Os extends List<Object>, depth extends Depth = 'flat', ignore extends Object = BuiltIn, fill extends any = never> = PatchAllImpl<O, Os, depth, ignore, fill>;

Utility Types

Core utility types for object operations.

/**
 * An Object type
 * @returns Record with any keys and values
 */
type Object = Record<Key, any>;

/**
 * Create an object filled with A for the fields K
 * @param K - Keys to choose fields
 * @param A - Type to fill fields with
 * @param modx - Modifiers for readonly/optional
 * @returns Object record type
 */
type Record<K extends Key, A extends any = unknown, modx extends Modx = ['!', 'W']> = {
    '!': {
        'R': { readonly [P in K]: A };
        'W': { [P in K]: A };
    };
    '?': {
        'R': { readonly [P in K]?: A };
        'W': { [P in K]?: A };
    };
}[modx[0]][modx[1]];

Property Modifications

Modify property characteristics like optionality, readonly status, and nullability.

/**
 * Make all properties optional
 * @param O - Object type to make partial
 * @returns Object with all optional properties
 */
type Partial<O extends Object> = { [K in keyof O]?: O[K] };

/**
 * Make all properties required
 * @param O - Object type to make required
 * @returns Object with all required properties
 */
type Required<O extends Object> = { [K in keyof O]-?: O[K] };

/**
 * Make all properties readonly
 * @param O - Object type to make readonly
 * @returns Object with all readonly properties
 */
type Readonly<O extends Object> = { readonly [K in keyof O]: O[K] };

/**
 * Make all properties writable (remove readonly)
 * @param O - Object type to make writable
 * @returns Object with all writable properties
 */
type Writable<O extends Object> = { -readonly [K in keyof O]: O[K] };

/**
 * Make all properties nullable
 * @param O - Object type to make nullable
 * @returns Object with all nullable properties
 */
type Nullable<O extends Object> = { [K in keyof O]: O[K] | null };

/**
 * Remove null and undefined from all properties
 * @param O - Object type to make non-nullable
 * @returns Object with non-nullable properties
 */
type NonNullable<O extends Object> = { [K in keyof O]: NonNullable<O[K]> };

/**
 * Make specific properties compulsory (required)
 * @param O - Object type to modify
 * @param K - Keys to make compulsory
 * @returns Object with specified properties made required
 */
type Compulsory<O extends Object, K extends keyof O> = O & Required<Pick<O, K>>;

/**
 * Make specific properties optional
 * @param O - Object type to modify
 * @param K - Keys to make optional
 * @returns Object with specified properties made optional
 */
type Optional<O extends Object, K extends keyof O> = Omit<O, K> & Partial<Pick<O, K>>;

Usage Examples:

import { O } from "ts-toolbelt";

type User = { 
  readonly name: string; 
  age: number; 
  email?: string; 
  active: boolean | null; 
};

type PartialUser = O.Partial<User>; 
// { readonly name?: string; age?: number; email?: string; active?: boolean | null }

type RequiredUser = O.Required<User>; 
// { readonly name: string; age: number; email: string; active: boolean | null }

type ReadonlyUser = O.Readonly<User>; 
// { readonly name: string; readonly age: number; readonly email?: string; readonly active: boolean | null }

type WritableUser = O.Writable<User>; 
// { name: string; age: number; email?: string; active: boolean | null }

type NullableUser = O.Nullable<User>; 
// { readonly name: string | null; age: number | null; email?: string | null; active: boolean | null }

type NonNullUser = O.NonNullable<User>; 
// { readonly name: string; age: number; email?: string; active: boolean }

type CompulsoryEmail = O.Compulsory<User, "email">; 
// { readonly name: string; age: number; email: string; active: boolean | null }

type OptionalAge = O.Optional<User, "age">; 
// { readonly name: string; age?: number; email?: string; active: boolean | null }

Property Operations

Advanced property manipulation including filtering, updating, and selective operations.

/**
 * Filter object properties based on condition
 * @param O - Object type to filter
 * @param M - Condition to filter by
 * @returns Object with filtered properties
 */
type Filter<O extends Object, M> = FilterImpl<O, M>;

/**
 * Update specific properties with new values
 * @param O - Object type to update
 * @param Path - Path to property to update
 * @param A - New value type
 * @returns Object with updated property
 */
type Update<O extends Object, Path extends string, A> = UpdateImpl<O, Path, A>;

/**
 * Modify properties using transformation function
 * @param O - Object type to modify
 * @param M - Modification mapping
 * @returns Object with modified properties
 */
type Modify<O extends Object, M> = ModifyImpl<O, M>;

/**
 * Replace properties with new types
 * @param O - Object type to modify
 * @param M - Replacement mapping
 * @returns Object with replaced properties
 */
type Replace<O extends Object, M extends Object> = Omit<O, keyof M> & M;

/**
 * Patch object with new properties (shallow merge)
 * @param O - Object type to patch
 * @param O1 - Properties to patch with
 * @returns Patched object
 */
type Patch<O extends Object, O1 extends Object> = O & O1;

/**
 * Overwrite properties from source object
 * @param O - Target object type
 * @param O1 - Source object type
 * @param K - Keys to overwrite
 * @returns Object with overwritten properties
 */
type Overwrite<O extends Object, O1 extends Object, K extends keyof O & keyof O1 = keyof O & keyof O1> = 
  Omit<O, K> & Pick<O1, K>;

Usage Examples:

import { O } from "ts-toolbelt";

type User = { name: string; age: number; email: string; active: boolean };

// Filter only string properties
type StringProps = O.Filter<User, string>; // { name: string; email: string }

// Update nested property
type UserProfile = { user: User; settings: { theme: string } };
type UpdatedProfile = O.Update<UserProfile, "settings.theme", "dark">; 
// { user: User; settings: { theme: "dark" } }

// Replace properties
type UserUpdates = { age: string; score: number };
type UpdatedUser = O.Replace<User, UserUpdates>; 
// { name: string; age: string; email: string; active: boolean; score: number }

// Patch with new properties
type UserExtensions = { lastLogin: Date; preferences: string[] };
type ExtendedUser = O.Patch<User, UserExtensions>; 
// { name: string; age: number; email: string; active: boolean; lastLogin: Date; preferences: string[] }

// Overwrite specific properties
type NewUserData = { age: string; active: string };
type OverwrittenUser = O.Overwrite<User, NewUserData>; 
// { name: string; age: string; email: string; active: string }

Path-Based Operations

Deep object manipulation using path notation for nested property access.

/**
 * Path-based property access using dot notation
 * @param O - Object type to access
 * @param Path - Dot-separated path to property
 * @returns Property type at path
 */
type AtPath<O extends Object, Path extends string> = AtPathImpl<O, Path>;

/**
 * Check if path exists in object
 * @param O - Object type to check
 * @param Path - Path to check for
 * @returns 1 if path exists, 0 otherwise
 */
type HasPath<O extends Object, Path extends string> = HasPathImpl<O, Path>;

/**
 * Namespace for path-based operations
 */
namespace P {
  type Pick<O extends Object, Path extends string> = PickPathImpl<O, Path>;
  type Omit<O extends Object, Path extends string> = OmitPathImpl<O, Path>;
  type Update<O extends Object, Path extends string, A> = UpdatePathImpl<O, Path, A>;
  type Merge<O1 extends Object, O2 extends Object> = MergePathImpl<O1, O2>;
  type Readonly<O extends Object, Path extends string> = ReadonlyPathImpl<O, Path>;
  type Record<Path extends string, A> = RecordPathImpl<Path, A>;
}

Usage Examples:

import { O } from "ts-toolbelt";

type UserProfile = {
  user: {
    name: string;
    details: {
      age: number;
      address: {
        street: string;
        city: string;
      };
    };
  };
  settings: {
    theme: string;
    notifications: boolean;
  };
};

type UserName = O.AtPath<UserProfile, "user.name">; // string
type UserAge = O.AtPath<UserProfile, "user.details.age">; // number
type City = O.AtPath<UserProfile, "user.details.address.city">; // string

type HasTheme = O.HasPath<UserProfile, "settings.theme">; // 1
type HasInvalidPath = O.HasPath<UserProfile, "user.invalid">; // 0

// Path-based operations using P namespace
type PickUserName = O.P.Pick<UserProfile, "user.name">; 
// { user: { name: string } }

type UpdateAge = O.P.Update<UserProfile, "user.details.age", string>; 
// UserProfile with age changed to string

type MergeSettings = O.P.Merge<UserProfile, { settings: { language: string } }>; 
// UserProfile with settings.language added

Key Extraction

Extract different types of keys based on property characteristics.

/**
 * Extract keys of properties that are optional
 * @param O - Object type to extract from
 * @returns Union of optional property keys
 */
type OptionalKeys<O extends Object> = OptionalKeysImpl<O>;

/**
 * Extract keys of properties that are required
 * @param O - Object type to extract from
 * @returns Union of required property keys
 */
type RequiredKeys<O extends Object> = RequiredKeysImpl<O>;

/**
 * Extract keys of properties that are readonly
 * @param O - Object type to extract from
 * @returns Union of readonly property keys
 */
type ReadonlyKeys<O extends Object> = ReadonlyKeysImpl<O>;

/**
 * Extract keys of properties that are writable
 * @param O - Object type to extract from
 * @returns Union of writable property keys
 */
type WritableKeys<O extends Object> = WritableKeysImpl<O>;

/**
 * Extract keys of properties that can be undefined
 * @param O - Object type to extract from
 * @returns Union of undefinable property keys
 */
type UndefinableKeys<O extends Object> = UndefinableKeysImpl<O>;

/**
 * Extract keys of properties that are compulsory (required and not undefined)
 * @param O - Object type to extract from
 * @returns Union of compulsory property keys
 */
type CompulsoryKeys<O extends Object> = CompulsoryKeysImpl<O>;

Usage Examples:

import { O } from "ts-toolbelt";

type User = {
  readonly id: string;
  name: string;
  age?: number;
  email?: string;
  active: boolean | undefined;
};

type OptionalKeys = O.OptionalKeys<User>; // "age" | "email"
type RequiredKeys = O.RequiredKeys<User>; // "id" | "name" | "active"
type ReadonlyKeys = O.ReadonlyKeys<User>; // "id"
type WritableKeys = O.WritableKeys<User>; // "name" | "age" | "email" | "active"
type UndefinableKeys = O.UndefinableKeys<User>; // "age" | "email" | "active"
type CompulsoryKeys = O.CompulsoryKeys<User>; // "id" | "name"

Types

// Core types used by Object module
type Object = Record<string | number | symbol, any>;
type Key = string | number | symbol;

Install with Tessl CLI

npx tessl i tessl/npm-ts-toolbelt

docs

any.md

boolean.md

class.md

community.md

function.md

index.md

iteration.md

list.md

misc.md

number.md

object.md

string.md

testing.md

union.md

tile.json