Tuple
Works with fixed-length arrays, also called tuples.
The runtime helpers in this module create new tuples instead of mutating their inputs, and the types preserve element positions where possible. The helpers cover tuple construction, indexed access, selecting or removing positions, appending values, transforming elements, renaming indices, mapping typed positions, and deriving comparison or combination helpers for tuple shapes.
Combining
appendElement
Signature
declare const appendElement: {
<E>(element: E): <T extends readonly Array<unknown>>(self: T) => [...Array<T>, E];
<T extends readonly Array<unknown>, E>(self: T, element: E): [...Array<T>, E];
}appendElements
Concatenates two tuples into a single tuple.
When to use
Use to append all elements from one tuple to another tuple.
Details
The result type is [...T1, ...T2], preserving all element types from both tuples. Neither input tuple is mutated; a fresh tuple is returned.
See
appendElement– append a single element
Signature
declare const appendElements: {
<T2 extends readonly Array<unknown>>(that: T2): <T1 extends readonly Array<unknown>>(self: T1) => [...Array<T1>, ...Array<T2>];
<T1 extends readonly Array<unknown>, T2 extends readonly Array<unknown>>(self: T1, that: T2): [...Array<T1>, ...Array<T2>];
}makeCombiner
Creates a Combiner for a tuple shape by providing a Combiner for each position. When two tuples are combined, each element is merged using its corresponding combiner.
When to use
Use when you need to merge two same-shape tuples by combining each position independently, such as summing counters or concatenating strings.
See
makeReducer– likemakeCombinerbut with an initial value
Signature
declare function makeCombiner<A extends readonly Array<unknown>>(combiners: { [K in string | number | symbol]: Combiner<A[K]> }): Combiner<A>Constructors
Creates a tuple from the provided arguments.
When to use
Use when you need a properly typed tuple without writing [a, b, c] as const or another manual cast.
Details
The returned value has the exact tuple type, with each element's literal type preserved.
See
get– access a single element by indexappendElement– append an element to a tuple
Signature
declare function make<Elements extends readonly Array<unknown>>(...elements: [...Array<Elements>]): [...Array<Elements>]Filtering
Creates a new tuple with the elements at the specified indices removed.
When to use
Use to drop elements from a tuple by position.
Details
Elements not at the specified indices are kept in their original order.
See
pick– the inverse (keep only specified indices)
Signature
declare const omit: {
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>>(indices: I): (self: T) => _BuildTuple<T, Exclude<Exclude<Partial<T>["length"], T["length"]>, I[number]>>;
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>>(self: T, indices: I): _BuildTuple<T, Exclude<Exclude<Partial<T>["length"], T["length"]>, I[number]>>;
}Creates a new tuple containing only the elements at the specified indices.
When to use
Use to select a subset of elements from a tuple by position.
Details
The result order matches the order of the provided indices.
See
Signature
declare const pick: {
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>>(indices: I): (self: T) => PickTuple<T, I>;
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>>(self: T, indices: I): PickTuple<T, I>;
}Folding
makeReducer
Creates a Reducer for a tuple shape by providing a Reducer for each position. The initial value is derived from each position's Reducer.initialValue. When reducing a collection of tuples, each element is combined independently.
When to use
Use when you need to fold same-shape tuples by accumulating each position independently into one summary tuple.
See
makeCombiner– likemakeReducerbut without an initial value
Signature
declare function makeReducer<A extends readonly Array<unknown>>(reducers: { [K in string | number | symbol]: Reducer<A[K]> }): Reducer<A>Getters
Retrieves the element at the specified index from a tuple.
When to use
Use when a single tuple element should be extracted in a pipeline.
Details
The index is constrained to valid tuple positions at the type level.
See
Signature
declare const get: {
<T extends readonly Array<unknown>, I extends never>(index: I): (self: T) => T[I];
<T extends readonly Array<unknown>, I extends never>(self: T, index: I): T[I];
}Guards
Checks whether a readonly array has exactly n elements.
When to use
Use when you need a Predicate guard for exact tuple length that narrows ReadonlyArray<T> to TupleOf<N, T>.
Details
This only checks length, not element types, and returns a refinement on the array type.
See
Signature
declare const isTupleOf: {
<N extends number>(n: N): <T>(self: readonly Array<T>) => self is TupleOf<N, T>;
<T, N extends number>(self: readonly Array<T>, n: N): self is TupleOf<N, T>;
}isTupleOfAtLeast
Checks whether a readonly array has at least n elements.
When to use
Use when you need a Predicate guard for tuple-like minimum length that narrows ReadonlyArray<T> to TupleOfAtLeast<N, T>.
Details
This only checks length, not element types, and returns a refinement on the array type.
See
Signature
declare const isTupleOfAtLeast: {
<N extends number>(n: N): <T>(self: readonly Array<T>) => self is [...Array<TupleOf<N, T>>, ...Array<T>];
<T, N extends number>(self: readonly Array<T>, n: N): self is [...Array<TupleOf<N, T>>, ...Array<T>];
}Instances
makeEquivalence
Creates an Equivalence for tuples by comparing corresponding elements using the provided per-position Equivalences. Two tuples are equivalent when all their corresponding elements are equivalent.
When to use
Use when you need an Equivalence to compare tuples element-by-element.
Details
This is an alias of Equivalence.Tuple.
See
makeOrder– create anOrderfor tuples
Signature
declare const makeEquivalence: <Elements extends readonly Array<Equivalence<any>>>(elements: Elements) => Equivalence<{ [I in string | number | symbol]: [Elements[I]] extends [Equivalence<A>] ? A : never }>Mapping
Transforms elements of a tuple by providing an array of transform functions. Each function applies to the element at the same position. Positions beyond the array's length are copied unchanged.
When to use
Use when you want to update the first N elements while keeping the rest.
Details
Each transform function receives the current value and can return a different type.
See
map– apply the same transformation to all elementsrenameIndices– swap element positions
Signature
declare const evolve: {
<T extends readonly Array<unknown>, E extends Evolver<T>>(evolver: E): (self: T) => Evolved<T, E>;
<T extends readonly Array<unknown>, E extends Evolver<T>>(self: T, evolver: E): Evolved<T, E>;
}Applies a Struct.Lambda transformation to every element in a tuple.
When to use
Use when you want to apply the same transformation to every tuple element.
Details
The lambda lets the compiler track the output type for each element.
Gotchas
The lambda must be created with Struct.lambda; a plain function will not type-check.
See
Signature
declare const map: {
<L extends Lambda>(lambda: L): <T extends readonly Array<unknown>>(self: T) => { [K in string | number | symbol]: Apply<L, T[K]> };
<T extends readonly Array<unknown>, L extends Lambda>(self: T, lambda: L): { [K in string | number | symbol]: Apply<L, T[K]> };
}Applies a Struct.Lambda transformation to all elements except those at the specified indices; the excluded elements are copied unchanged.
When to use
Use when most elements should be transformed but a few should be preserved.
See
Signature
declare const mapOmit: {
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>, L extends Lambda>(indices: I, lambda: L): (self: T) => { [K in string | number | symbol]: K extends `${I[number]}` ? T[K] : Apply<L, T[K]> };
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>, L extends Lambda>(self: T, indices: I, lambda: L): { [K in string | number | symbol]: K extends `${I[number]}` ? T[K] : Apply<L, T[K]> };
}Applies a Struct.Lambda transformation only to the elements at the specified indices; all other elements are copied unchanged.
When to use
Use when you want to apply the same transformation to a subset of positions.
See
Signature
declare const mapPick: {
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>, L extends Lambda>(indices: I, lambda: L): (self: T) => { [K in string | number | symbol]: K extends `${I[number]}` ? Apply<L, T[K]> : T[K] };
<T extends readonly Array<unknown>, I extends readonly Array<Exclude<Partial<T>["length"], T["length"]>>, L extends Lambda>(self: T, indices: I, lambda: L): { [K in string | number | symbol]: K extends `${I[number]}` ? Apply<L, T[K]> : T[K] };
}Ordering
Creates an Order for tuples by comparing corresponding elements using the provided per-position Orders. Elements are compared left-to-right; the first non-zero comparison determines the result.
When to use
Use when you need to sort fixed-position arrays lexicographically, with each position using its own ordering rule.
Details
This is an alias of Order.Tuple.
See
makeEquivalence– create anEquivalencefor tuples
Signature
declare const makeOrder: <Elements extends readonly Array<Order<any>>>(elements: Elements) => Order<{ [I in string | number | symbol]: [Elements[I]] extends [Order<A>] ? A : never }>Transforming
renameIndices
Renames tuple indices by providing an array of stringified source indices. Each position in the array specifies which index to read from (e.g., ["2", "1", "0"] reverses a 3-element tuple).
When to use
Use to reorder tuple elements while preserving index-specific types.
Details
The mapping returns a tuple in the requested index order.
Gotchas
The mapping uses stringified source indices, not arbitrary names.
See
evolve– transform element values instead of positions
Signature
declare const renameIndices: {
<T extends readonly Array<unknown>, M extends { [I in string | number | symbol]: `${keyof T & string}` }>(mapping: M): (self: T) => { [I in string | number | symbol]: I extends keyof M ? M[I] extends keyof T ? T[any[any]] : T[I] : T[I] };
<T extends readonly Array<unknown>, M extends { [I in string | number | symbol]: `${keyof T & string}` }>(self: T, mapping: M): { [I in string | number | symbol]: I extends keyof M ? M[I] extends keyof T ? T[any[any]] : T[I] : T[I] };
}
Appends a single element to the end of a tuple.
When to use
Use when you need the appended value to remain part of the tuple's type-level shape and preserve literal element positions.
Details
The result type is
[...T, E], preserving all existing element types.See
appendElements– append multiple elements (another tuple)