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

list.mddocs/

List Module

Comprehensive array and tuple manipulation utilities - the largest module with 73+ operations for transforming, accessing, and modifying list types.

Capabilities

Core Manipulation

Essential operations for adding, removing, and rearranging list elements.

/**
 * Add element to the end of list
 * @param L - List to append to
 * @param A - Element to append
 * @returns New list with element appended
 */
type Append<L extends List, A> = [...L, A];

/**
 * Add element to the beginning of list
 * @param L - List to prepend to
 * @param A - Element to prepend
 * @returns New list with element prepended
 */
type Prepend<L extends List, A> = [A, ...L];

/**
 * Concatenate two lists
 * @param L1 - First list
 * @param L2 - Second list
 * @returns Combined list
 */
type Concat<L1 extends List, L2 extends List> = [...L1, ...L2];

/**
 * Reverse the order of elements in list
 * @param L - List to reverse
 * @returns List with elements in reverse order
 */
type Reverse<L extends List> = ReverseImpl<L>;

/**
 * Remove last element from list
 * @param L - List to pop from
 * @returns List without last element
 */
type Pop<L extends List> = L extends readonly [...infer Rest, any] ? Rest : [];

/**
 * Remove first N elements from list
 * @param L - List to drop from
 * @param N - Number of elements to drop
 * @returns List without first N elements
 */
type Drop<L extends List, N extends number> = DropImpl<L, N>;

/**
 * Take first N elements from list
 * @param L - List to take from
 * @param N - Number of elements to take
 * @returns List with only first N elements
 */
type Take<L extends List, N extends number> = TakeImpl<L, N>;

Usage Examples:

import { L } from "ts-toolbelt";

type Numbers = [1, 2, 3];
type Letters = ["a", "b"];

type WithFour = L.Append<Numbers, 4>; // [1, 2, 3, 4]
type WithZero = L.Prepend<Numbers, 0>; // [0, 1, 2, 3]
type Combined = L.Concat<Numbers, Letters>; // [1, 2, 3, "a", "b"]
type Reversed = L.Reverse<Numbers>; // [3, 2, 1]
type Popped = L.Pop<Numbers>; // [1, 2]
type DropTwo = L.Drop<[1, 2, 3, 4, 5], 2>; // [3, 4, 5]
type TakeTwo = L.Take<[1, 2, 3, 4, 5], 2>; // [1, 2]

Access Operations

Get specific elements and information from lists.

/**
 * Get element at specific index
 * @param L - List to access
 * @param K - Index to access
 * @returns Element at index K
 */
type At<L extends List, K extends number> = L[K];

/**
 * Get first element of list
 * @param L - List to get head from
 * @returns First element or never if empty
 */
type Head<L extends List> = L extends readonly [infer H, ...any[]] ? H : never;

/**
 * Get all elements except first
 * @param L - List to get tail from
 * @returns List without first element
 */
type Tail<L extends List> = L extends readonly [any, ...infer T] ? T : [];

/**
 * Get last element of list
 * @param L - List to get last from
 * @returns Last element or never if empty
 */
type Last<L extends List> = L extends readonly [...any[], infer L] ? L : never;

/**
 * Get length of list
 * @param L - List to measure
 * @returns Length as number literal
 */
type Length<L extends List> = L['length'];

/**
 * Extract valid keys (indices) from list
 * @param L - List to extract keys from
 * @returns Union of valid indices
 */
type Keys<L extends List> = Exclude<keyof L, keyof []>;

/**
 * Extract known keys (non-index signature) from list
 * @param L - List to extract known keys from
 * @returns Union of known indices
 */
type KnownKeys<L extends List> = KnownKeysImpl<L>;

Usage Examples:

import { L } from "ts-toolbelt";

type Items = ["apple", "banana", "cherry"];

type Second = L.At<Items, 1>; // "banana"
type First = L.Head<Items>; // "apple"
type Rest = L.Tail<Items>; // ["banana", "cherry"]
type Last = L.Last<Items>; // "cherry"
type Count = L.Length<Items>; // 3
type Indices = L.Keys<Items>; // 0 | 1 | 2
type KnownIndices = L.KnownKeys<Items>; // 0 | 1 | 2

// With mixed tuple
type Mixed = [string, number, ...boolean[]];
type MixedKeys = L.Keys<Mixed>; // number (includes index signature)
type MixedKnown = L.KnownKeys<Mixed>; // 0 | 1

Query Operations

Check membership, inclusion, and constraints on lists.

/**
 * Check if list contains specific element
 * @param L - List to check
 * @param A - Element to look for
 * @returns 1 if element is found, 0 otherwise
 */
type Has<L extends List, A> = A extends L[number] ? 1 : 0;

/**
 * Check if list includes element (alias for Has)
 * @param L - List to check
 * @param A - Element to look for
 * @returns 1 if element is included, 0 otherwise
 */
type Includes<L extends List, A> = Has<L, A>;

/**
 * Ensure list has at least N elements
 * @param L - List to check
 * @param N - Minimum number
 * @returns List type with at least N elements constraint
 */
type AtLeast<L extends List, N extends number> = AtLeastImpl<L, N>;

Usage Examples:

import { L } from "ts-toolbelt";

type Fruits = ["apple", "banana", "cherry"];

type HasApple = L.Has<Fruits, "apple">; // 1
type HasOrange = L.Has<Fruits, "orange">; // 0
type IncludesBanana = L.Includes<Fruits, "banana">; // 1

// AtLeast constraint
type AtLeastTwo = L.AtLeast<[string, number], 2>; // [string, number]
type AtLeastFive = L.AtLeast<[string], 5>; // Constraint ensures minimum 5 elements

Transformation Operations

Transform lists using mapping, filtering, and grouping operations.

/**
 * Filter list elements based on condition
 * @param L - List to filter
 * @param M - Condition to filter by
 * @returns List with elements matching condition
 */
type Filter<L extends List, M> = FilterImpl<L, M>;

/**
 * Group list elements by criteria
 * @param L - List to group
 * @param K - Grouping criteria
 * @returns Grouped structure
 */
type Group<L extends List, K> = GroupImpl<L, K>;

/**
 * Flatten nested lists
 * @param L - List to flatten
 * @param depth - Flatten depth
 * @returns Flattened list
 */
type Flatten<L extends List, depth extends number = 1> = FlattenImpl<L, depth>;

/**
 * Zip two lists together
 * @param L1 - First list
 * @param L2 - Second list
 * @returns List of paired elements
 */
type Zip<L1 extends List, L2 extends List> = ZipImpl<L1, L2>;

/**
 * Create object from list of keys and list of values
 * @param K - List of keys
 * @param V - List of values
 * @returns Object with zipped key-value pairs
 */
type ZipObj<K extends readonly (string | number | symbol)[], V extends List> = ZipObjImpl<K, V>;

/**
 * Convert list to object with indices as keys
 * @param L - List to convert
 * @returns Object representation of list
 */
type ObjectOf<L extends List> = { [K in keyof L]: L[K] };

/**
 * Convert object to list of values
 * @param O - Object to convert
 * @returns List of object values
 */
type ListOf<O extends Record<number, any>> = ListOfImpl<O>;

Usage Examples:

import { L } from "ts-toolbelt";

type Numbers = [1, 2, 3, 4, 5];
type Mixed = [string, number, boolean];

// Filter even numbers (conceptual - actual implementation varies)
type EvenNumbers = L.Filter<Numbers, 2 | 4>; // [2, 4]

// Zip lists
type List1 = ["a", "b", "c"];
type List2 = [1, 2, 3];
type Zipped = L.Zip<List1, List2>; // [["a", 1], ["b", 2], ["c", 3]]

// Zip to object
type Keys = ["name", "age", "active"];
type Values = [string, number, boolean];
type UserSchema = L.ZipObj<Keys, Values>; // { name: string; age: number; active: boolean }

// List to object conversion
type ListAsObj = L.ObjectOf<["a", "b", "c"]>; // { 0: "a"; 1: "b"; 2: "c" }

// Object to list conversion
type ObjAsList = L.ListOf<{ 0: "a"; 1: "b"; 2: "c" }>; // ["a", "b", "c"]

// Flatten nested arrays
type Nested = [[1, 2], [3, [4, 5]]];
type FlatOnce = L.Flatten<Nested>; // [1, 2, 3, [4, 5]]
type FlatDeep = L.Flatten<Nested, 2>; // [1, 2, 3, 4, 5]

Set Operations

Operations treating lists as sets for intersection, difference, and exclusion.

/**
 * Set difference - elements in L1 but not in L2
 * @param L1 - First list
 * @param L2 - Second list
 * @returns Elements unique to first list
 */
type Diff<L1 extends List, L2 extends List> = DiffImpl<L1, L2>;

/**
 * Set intersection - elements common to both lists
 * @param L1 - First list
 * @param L2 - Second list
 * @returns Common elements
 */
type Intersect<L1 extends List, L2 extends List> = IntersectImpl<L1, L2>;

/**
 * Exclude specific elements from list
 * @param L - List to exclude from
 * @param A - Elements to exclude
 * @returns List without excluded elements
 */
type Exclude<L extends List, A> = ExcludeImpl<L, A>;

/**
 * Extract specific elements from list
 * @param L - List to extract from
 * @param A - Elements to extract
 * @returns List with only extracted elements
 */
type Extract<L extends List, A> = ExtractImpl<L, A>;

/**
 * Remove duplicate elements from list
 * @param L - List to deduplicate
 * @returns List with unique elements only
 */
type Unique<L extends List> = UniqueImpl<L>;

Usage Examples:

import { L } from "ts-toolbelt";

type List1 = [1, 2, 3, 4];
type List2 = [3, 4, 5, 6];

type Difference = L.Diff<List1, List2>; // [1, 2]
type Common = L.Intersect<List1, List2>; // [3, 4]
type WithoutNumbers = L.Exclude<[1, "a", 2, "b"], number>; // ["a", "b"]
type OnlyNumbers = L.Extract<[1, "a", 2, "b"], number>; // [1, 2]

type WithDuplicates = [1, 2, 2, 3, 3, 3];
type UniqueOnly = L.Unique<WithDuplicates>; // [1, 2, 3]

Key Operations

Operations for working with list keys, indices, and key-based filtering.

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

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

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

/**
 * Create a set of keys from range
 * @param From - Starting index
 * @param To - Ending index
 * @returns Union of keys in range
 */
type KeySet<From extends number, To extends number> = KeySetImpl<From, To>;

/**
 * Get the last index of L
 * @param L - List to get last index from
 * @returns Last valid index number
 */
type LastKey<L extends List> = Length<Tail<L>>;

Key Classifications

Operations for categorizing keys by their type characteristics.

/**
 * Get the keys of L that are optional
 * @param L - List to extract from
 * @returns Union of optional keys
 */
type OptionalKeys<L extends List> = OptionalKeysImpl<L>;

/**
 * Get the keys of L that are required
 * @param L - List to extract from
 * @returns Union of required keys
 */
type RequiredKeys<L extends List> = RequiredKeysImpl<L>;

/**
 * Get the keys of L that are readonly
 * @param L - List to extract from
 * @returns Union of readonly keys
 */
type ReadonlyKeys<L extends List> = ReadonlyKeysImpl<L>;

/**
 * Get the keys of L that are writable
 * @param L - List to extract from
 * @returns Union of writable keys
 */
type WritableKeys<L extends List> = WritableKeysImpl<L>;

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

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

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

Path Operations

Operations for navigating and accessing nested properties in lists.

/**
 * Get the type at nested path in L
 * @param L - List to be inspected
 * @param Path - Path to be followed
 * @returns Type at the specified path
 */
type Path<L extends List, Path extends List<Key>> = PathImpl<L, Path>;

/**
 * Get all possible paths of L
 * @param L - List to be inspected
 * @returns Union of all possible paths
 */
type Paths<L extends List> = PathsImpl<L>;

/**
 * Check whether L has nested entries that match M
 * @param L - List to be inspected
 * @param Path - Path to be followed
 * @param M - Type to check entry type
 * @param match - Precision mode for matching
 * @returns 1 if path exists and matches, 0 otherwise
 */
type HasPath<L extends List, Path extends List<Key>, M extends any = any, match extends Match = 'default'> = HasPathImpl<L, Path, M, match>;

Range Operations

Operations for extracting and removing ranges of elements.

/**
 * Pick a range of entries from L
 * @param L - List to pick from
 * @param From - Starting index
 * @param To - Ending index
 * @returns List containing elements in range
 */
type Extract<L extends List, From extends number, To extends number> = Pick<L, KeySet<From, To>>;

/**
 * Remove a range of entries from L
 * @param L - List to remove from
 * @param From - Starting index
 * @param To - Ending index
 * @returns List without elements in range
 */
type Remove<L extends List, From extends number, To extends number> = Omit<L, KeySet<From, To>>;

List Modification Operations

Advanced operations for modifying, patching, and updating list elements.

/**
 * Assign a list of Lists into L with Merge
 * @param L - List to assign to
 * @param Ls - Lists to assign
 * @param depth - Merge depth ('flat' or 'deep')
 * @param ignore - Types not to merge
 * @param fill - Types to be replaced
 * @returns Modified list
 */
type Assign<L extends List, Ls extends List<List>, depth extends Depth = 'flat', ignore extends object = BuiltIn, fill extends any = never> = Cast<OAssign<L, Ls, depth, ignore, fill>, List>;

/**
 * Update the entries of L with the ones of L1
 * @param L - List to update
 * @param L1 - List to update with
 * @returns Updated list
 */
type Overwrite<L extends List, L1 extends object> = OverwriteImpl<L, L1>;

/**
 * Modify L with LMod using placeholder substitution
 * @param L - List to copy from
 * @param LMod - Modification template
 * @returns Modified list
 */
type Modify<L extends List, LMod extends List> = ModifyImpl<L, LMod>;

/**
 * Complete the fields of L with the ones of L1
 * @param L - List to complete
 * @param L1 - List to copy from
 * @param depth - Patch depth ('flat' or 'deep')
 * @param ignore - Types not to merge
 * @param fill - Types to be replaced
 * @returns Patched list
 */
type Patch<L extends List, L1 extends List, depth extends Depth = 'flat', ignore extends object = BuiltIn, fill extends any = never> = PatchImpl<L, L1, depth, ignore, fill>;

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

List Utility Operations

Utility operations for list generation, comparison, and transformation.

/**
 * Fill a List with N repetitions of A
 * @param A - Element to fill with
 * @param N - Number of repetitions
 * @param L - Initial list (empty by default)
 * @returns List filled with repeated elements
 */
type Repeat<A extends any, N extends number, L extends List = []> = RepeatImpl<A, N, L>;

/**
 * Transform a List into a Union
 * @param L - List to transform
 * @returns Union of all list elements
 */
type UnionOf<L extends List> = L[number];

/**
 * Remove a dimension from nested L
 * @param L - List to un-nest
 * @param strict - Whether to preserve tuples
 * @returns Flattened list
 */
type UnNest<L extends List, strict extends Boolean = 1> = UnNestImpl<L, strict>;

/**
 * Get the longest List of L & L1
 * @param L - First list to compare
 * @param L1 - Second list to compare
 * @returns Longer of the two lists
 */
type Longest<L extends List, L1 extends List> = LongestImpl<L, L1>;

/**
 * Get the shortest List of L & L1
 * @param L - First list to compare
 * @param L1 - Second list to compare
 * @returns Shorter of the two lists
 */
type Shortest<L extends List, L1 extends List> = ShortestImpl<L, L1>;

/**
 * Split L into a Union where none of the K keys are present together
 * @param L - List to split
 * @param K - Keys to split with
 * @param strict - Force excess property checks
 * @returns List union with mutually exclusive keys
 */
type Either<L extends List, K extends Key, strict extends Boolean = 1> = OEither<ObjectOf<L>, `${K & number}` | K, strict> extends infer OE ? OE extends unknown ? _ListOf<OE & {}> : never : never;

Property Modifications

Modify characteristics of list elements like optionality, nullability, and readonly status.

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

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

/**
 * Make all list elements readonly
 * @param L - List to make readonly
 * @returns Readonly list
 */
type Readonly<L extends List> = { readonly [K in keyof L]: L[K] };

/**
 * Make all list elements writable
 * @param L - List to make writable
 * @returns Writable list
 */
type Writable<L extends List> = { -readonly [K in keyof L]: L[K] };

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

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

/**
 * Make all list elements undefinable
 * @param L - List to make undefinable
 * @returns List with undefinable elements
 */
type Undefinable<L extends List> = { [K in keyof L]: L[K] | undefined };

Usage Examples:

import { L } from "ts-toolbelt";

type StrictList = readonly [string, number, boolean];

type OptionalList = L.Partial<StrictList>; // [string?, number?, boolean?]
type RequiredList = L.Required<OptionalList>; // [string, number, boolean]
type ReadonlyList = L.Readonly<[string, number]>; // readonly [string, number]
type WritableList = L.Writable<ReadonlyList>; // [string, number]

type NullableList = L.Nullable<[string, number]>; // [string | null, number | null]
type NonNullList = L.NonNullable<[string | null, number | undefined]>; // [string, number]
type UndefinableList = L.Undefinable<[string, number]>; // [string | undefined, number | undefined]

Advanced Operations

Complex operations for merging, updating, and transforming lists.

/**
 * Merge two lists element-wise
 * @param L1 - First list
 * @param L2 - Second list
 * @returns Merged list
 */
type Merge<L1 extends List, L2 extends List> = MergeImpl<L1, L2>;

/**
 * Merge multiple lists
 * @param Ls - Array of lists to merge
 * @returns Single merged list
 */
type MergeAll<Ls extends readonly List[]> = MergeAllImpl<Ls>;

/**
 * Update element at specific index
 * @param L - List to update
 * @param K - Index to update
 * @param A - New value
 * @returns List with updated element
 */
type Update<L extends List, K extends number, A> = UpdateImpl<L, K, A>;

/**
 * Remove elements at specific indices
 * @param L - List to remove from
 * @param K - Indices to remove
 * @returns List without removed elements
 */
type Remove<L extends List, K extends number> = RemoveImpl<L, K>;

/**
 * Replace all occurrences of element
 * @param L - List to replace in
 * @param From - Element to replace
 * @param To - Replacement element
 * @returns List with replacements
 */
type Replace<L extends List, From, To> = ReplaceImpl<L, From, To>;

/**
 * Select elements based on condition
 * @param L - List to select from
 * @param C - Selection condition
 * @returns Selected elements
 */
type Select<L extends List, C> = SelectImpl<L, C>;

/**
 * Convert list to union type
 * @param L - List to unionize
 * @returns Union of all list elements
 */
type Unionize<L extends List> = L[number];

Usage Examples:

import { L } from "ts-toolbelt";

type List1 = [1, 2, 3];
type List2 = ["a", "b", "c"];

type Merged = L.Merge<List1, List2>; // [1 | "a", 2 | "b", 3 | "c"]
type MergedMultiple = L.MergeAll<[List1, List2, [true, false, true]]>; 
// [1 | "a" | true, 2 | "b" | false, 3 | "c" | true]

type Updated = L.Update<[1, 2, 3], 1, "two">; // [1, "two", 3]
type Removed = L.Remove<[1, 2, 3, 4], 1>; // [1, 3, 4]
type Replaced = L.Replace<[1, 2, 1, 3], 1, "one">; // ["one", 2, "one", 3]

type AsUnion = L.Unionize<["a", "b", "c"]>; // "a" | "b" | "c"

Types

// Core types used by List module
type List<A = any> = readonly A[];

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