Variadic Tuple Types
A variadic tuple type places a spread element inside a tuple — like or — letting its length and element types vary with a type parameter so functions such as concat and curry stay precisely typed.
Learn Variadic Tuple Types in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Think of a train. A plain array is "some carriages" — you've forgotten which is the engine and which is the caboose. A variadic tuple is the precise consist: "engine, then these middle carriages, then the caboose." [first, ...rest] says "engine plus whatever follows"; [...rest, last] says "whatever comes before, then the caboose." Every carriage keeps its exact role and position, no matter how many sit in the middle.
1. Spreads Inside Tuple Types
A spread element inside a tuple type makes it variadic : is "a number, then however many elements T describes." The spread can sit at the start, middle, or end, mirroring how the array spread operator works at runtime — though a tuple type may contain at most one rest element.
2. Typing concat & Labeled Elements
The headline use is a concat whose return type is : it joins two tuples while keeping every element's type and position, so result[0] stays a number . Labeled tuple elements like add names for readability — type-only, never at runtime.
3. Rest Parameters as Tuples & Currying
TypeScript types a function's ...args as a tuple , so variadic tuples are what make bind , currying , and partial application type-safe. Splitting a parameter tuple into a head and tail — — lets you fix some arguments now and supply the rest later, each part fully typed.
🎯 Your Turn
Build the runtime behind — put head first, then spread the rest. Fill in the two blanks marked ___ , then run it.
No blanks this time — just a brief and a starting outline. Build the tuple-preserving helpers yourself, run them, and check your output against the example in the comments.
Practice quiz
A variadic tuple type is a tuple that includes:
- At least five elements
- Only optional elements
- A spread element referencing a type parameter
- No elements
Answer: A spread element referencing a type parameter. A spread inside a tuple type, like [first, ...rest], makes its length and contents vary with a type parameter.
The runtime equivalent of the type-level [...T, ...U] is:
- The array spread operator
- A for loop only
- Object.assign
- JSON.stringify
Answer: The array spread operator. Spreading both arrays into one ([...a, ...b]) mirrors the variadic tuple type exactly.
How many rest elements may a single tuple type contain?
- Zero
- Exactly two
- Unlimited
- At most one
Answer: At most one. A tuple type may have at most one rest element; [...string[], ...number[]] is an error.
Compared to (number | string)[], a variadic tuple [...T, ...U]:
- Forgets positions
- Keeps each element's type and position
- Is always shorter
- Cannot be returned
Answer: Keeps each element's type and position. A variadic tuple preserves exact types and positions, so result[0] can be known as number.
Labeled tuple elements like [x: number, y: number] are:
- Purely for readability, type-only
- Accessible at runtime as keys
- Required for variadic tuples
- A kind of union
Answer: Purely for readability, type-only. Labels document each slot for editors and readers but do not exist at runtime.
In TypeScript, a function's ...args rest parameter is typed as a:
- Union
- Record
- Tuple
- Promise
Answer: Tuple. Rest parameters are typed as a tuple, which is what makes typed bind, curry, and partial possible.
The spread element in a variadic tuple type may appear:
- Only at the end
- At the start, middle, or end
- Only at the start
- Never inside a tuple
Answer: At the start, middle, or end. Modern TypeScript allows the single rest element at the start, middle, or end.
[id: number, ...rest: T] where T is [string, boolean] describes:
The spread expands T's elements after the leading number, giving [id: number, string, boolean].
Parameters<(a: string, b: number) => void> is:
- string | number
Parameters extracts the argument types as a tuple — here [string, number].
Variadic tuples are most useful whenever an array's:
- Length is unknown
- Elements are all identical
- Positions matter
- Values are strings
Answer: Positions matter. They avoid losing type precision through helpers when each position's type matters.