All essential TypeScript types in one place providing 70+ utility types and helper functions.
—
Specialized types for working with arrays, tuples, and array-like structures with type safety. These utilities help you manipulate and constrain array types effectively.
Matches Array<Type> or ReadonlyArray<Type> where Type is any by default.
type AnyArray<Type = any> = Array<Type> | ReadonlyArray<Type>;Usage Example:
import type { AnyArray } from "ts-essentials";
type StringArrays = AnyArray<string>; // Array<string> | ReadonlyArray<string>
function processArray<T>(arr: AnyArray<T>): T[] {
return Array.from(arr);
}
// Works with both mutable and readonly arrays
processArray([1, 2, 3]); // Array<number>
processArray(["a", "b"] as const); // readonly string[]Matches Type or Type[], useful for APIs that accept either a single value or an array.
type ArrayOrSingle<Type> = Type | Type[];Usage Example:
import type { ArrayOrSingle } from "ts-essentials";
function addTags(tags: ArrayOrSingle<string>): string[] {
return Array.isArray(tags) ? tags : [tags];
}
// Both calls are valid
addTags("javascript"); // Works with single string
addTags(["javascript", "typescript"]); // Works with array
// API design example
interface SearchOptions {
query: string;
categories: ArrayOrSingle<string>;
sort: ArrayOrSingle<"date" | "relevance">;
}Matches Type or readonly Type[], similar to ArrayOrSingle but with readonly constraint.
type ReadonlyArrayOrSingle<Type> = Type | readonly Type[];Usage Example:
import type { ReadonlyArrayOrSingle } from "ts-essentials";
function processReadonlyData<T>(data: ReadonlyArrayOrSingle<T>): readonly T[] {
return Array.isArray(data) ? data : [data] as const;
}
// Usage with readonly arrays
const result = processReadonlyData(["a", "b"] as const);
// result is readonly string[]Constructs a type which equals to array element type for type Type.
type ElementOf<Type> = Type extends ReadonlyArray<infer U> ? U : never;Usage Example:
import type { ElementOf } from "ts-essentials";
type StringArray = string[];
type ArrayElement = ElementOf<StringArray>; // string
type TupleArray = [number, string, boolean];
type TupleElement = ElementOf<TupleArray>; // number | string | boolean
// Useful for generic functions working with array elements
function processElements<T extends ReadonlyArray<any>>(
arr: T,
processor: (element: ElementOf<T>) => ElementOf<T>
): T {
return arr.map(processor) as T;
}
const numbers = [1, 2, 3];
const doubled = processElements(numbers, x => x * 2); // number[]Constructs a type which equals to first element in type Type.
type Head<Type extends ReadonlyArray<any>> = Type extends readonly [infer H, ...any[]] ? H : never;Usage Example:
import type { Head } from "ts-essentials";
type Tuple = [string, number, boolean];
type FirstElement = Head<Tuple>; // string
type EmptyTuple = [];
type EmptyHead = Head<EmptyTuple>; // never
// Runtime helper function
function getHead<T extends ReadonlyArray<any>>(arr: T): Head<T> | undefined {
return arr[0] as Head<T> | undefined;
}
const tuple = ["hello", 42, true] as const;
const head = getHead(tuple); // "hello"Constructs a type which equals to elements but first one in type Type.
type Tail<Type extends ReadonlyArray<any>> = Type extends readonly [any, ...infer T] ? T : [];Usage Example:
import type { Tail } from "ts-essentials";
type Tuple = [string, number, boolean];
type RestElements = Tail<Tuple>; // [number, boolean]
type SingleTuple = [string];
type SingleTail = Tail<SingleTuple>; // []
// Runtime helper function
function getTail<T extends ReadonlyArray<any>>(arr: T): Tail<T> {
return arr.slice(1) as Tail<T>;
}
const tuple = ["hello", 42, true] as const;
const tail = getTail(tuple); // [42, true]Matches array with at least one element of type Type.
type NonEmptyArray<Type> = [Type, ...Type[]];Usage Example:
import type { NonEmptyArray } from "ts-essentials";
function processNonEmptyArray<T>(arr: NonEmptyArray<T>): T {
return arr[0]; // Safe to access first element
}
// Type-safe functions that require non-empty arrays
function findMax(numbers: NonEmptyArray<number>): number {
return Math.max(...numbers);
}
// This works
findMax([1, 2, 3]); // OK
// This would cause a compile error:
// findMax([]); // Error: Argument of type '[]' is not assignable
// Type guard for runtime checking
function isNonEmptyArray<T>(arr: T[]): arr is NonEmptyArray<T> {
return arr.length > 0;
}
function safeProcessArray<T>(arr: T[]): T | undefined {
if (isNonEmptyArray(arr)) {
return processNonEmptyArray(arr); // Type-safe!
}
return undefined;
}Matches type constraint for tuple with elements of type Type (any by default).
type Tuple<Type = any> = readonly Type[];Usage Example:
import type { Tuple } from "ts-essentials";
// Generic tuple constraint
function processTuple<T extends Tuple>(tuple: T): T {
return tuple;
}
// Works with any tuple
processTuple([1, 2, 3] as const);
processTuple(["a", "b"] as const);
// Typed tuple constraint
function processStringTuple<T extends Tuple<string>>(tuple: T): T {
return tuple;
}
processTuple(["hello", "world"] as const); // OK
// processTuple([1, 2] as const); // Error: not all elements are stringsCombine array and tuple utilities for complex operations:
import type {
NonEmptyArray,
Head,
Tail,
ElementOf,
ArrayOrSingle
} from "ts-essentials";
// Recursive tuple processing
type ProcessTuple<T extends ReadonlyArray<any>> = T extends NonEmptyArray<any>
? [ProcessElement<Head<T>>, ...ProcessTuple<Tail<T>>]
: [];
type ProcessElement<T> = T extends string ? `processed_${T}` : T;
type Example = ProcessTuple<["hello", "world", 42]>;
// Result: ["processed_hello", "processed_world", 42]
// Safe array operations
function safeArrayOperation<T extends ReadonlyArray<any>>(
arr: T
): {
first: Head<T> | undefined;
rest: Tail<T>;
elementType: ElementOf<T> | undefined
} {
return {
first: arr[0] as Head<T> | undefined,
rest: arr.slice(1) as Tail<T>,
elementType: arr[0] as ElementOf<T> | undefined
};
}
// Flexible input handling
function flexibleInput<T>(input: ArrayOrSingle<T>): NonEmptyArray<T> | never {
const arr = Array.isArray(input) ? input : [input];
if (arr.length === 0) {
throw new Error("Input cannot be empty");
}
return arr as NonEmptyArray<T>;
}type ReadonlyArray<T> = readonly T[];
type Array<T> = T[];Install with Tessl CLI
npx tessl i tessl/npm-ts-essentials