1. Introduction
Some functions need to accept a variable number of arguments — a logging function, a sum function, or a function that forwards arguments to another API. JavaScript's rest parameter syntax (...args) gathers all remaining arguments into a single array, and TypeScript extends this by requiring that array to be given an element type, so every gathered argument is still type-checked.
Cricket analogy: A function tallying a batter's scores across an unknown number of innings, like totalRuns(...scores: number[]), mirrors how rest parameters gather every remaining argument into a typed array instead of a loosely typed list.
Rest parameters are a typed, more flexible alternative to the old arguments object, and they compose naturally with the spread operator when calling other functions.
Cricket analogy: Instead of the old loosely typed arguments object, a scoring function uses typed rest parameters, and when forwarding those scores to another function like logInnings(...allScores), the spread operator composes naturally with it.
2. Syntax
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
function logEvent(eventName: string, ...details: string[]): void {
console.log(eventName, details.join(", "));
}
sum(1, 2, 3, 4);
logEvent("login", "userId=42", "ip=10.0.0.1");3. Explanation
A rest parameter is written with three dots before the parameter name, ...name: Type[], and its declared type must be an array type (or a tuple type for fixed-shape variadic patterns). Inside the function, numbers behaves like a normal number[] array — you can call .length, .map, .reduce, and every other array method on it directly, no matter how many arguments the caller passed.
Cricket analogy: function totalRuns(...scores: number[]) gathers every innings score into a real number[], so inside the function you can call scores.reduce() to sum them, no matter whether a batter played 2 innings or 20.
Because a rest parameter absorbs every argument from its position to the end of the call, it must be the last parameter in the function's signature. Any parameters that come before it are matched positionally as usual, and everything left over is collected into the rest array.
Cricket analogy: In function scoreCard(matchDate: string, ...innings: number[]), matchDate is matched positionally first, and every remaining argument is collected into innings, so the rest parameter must come last in the signature.
The spread operator is the natural counterpart to rest parameters: sum(...[1, 2, 3]) spreads an existing array back out into individual arguments, letting you forward a dynamically-sized array of values into a rest-parameter function.
A rest parameter must be the last parameter and there can only be one per function — function f(...a: number[], b: string) is a compile error. Also, forgetting the array type (...numbers) makes TypeScript infer any[] in older loose configs or report an implicit-any error under noImplicitAny, losing all type safety on the collected arguments.
4. Example
function buildPath(base: string, ...segments: string[]): string {
return segments.reduce((path, segment) => `${path}/${segment}`, base);
}
console.log(buildPath("/api", "users", "42", "orders"));
console.log(buildPath("/api"));
const parts = ["v2", "products"];
console.log(buildPath("/api", ...parts));5. Output
/api/users/42/orders
/api
/api/v2/products6. Key Takeaways
- A rest parameter is written
...name: Type[]and gathers all remaining arguments into a typed array. - Rest parameters must be typed as an array (or tuple) type and are checked element-by-element like normal arrays.
- A rest parameter must be the last parameter in the function signature, and only one is allowed per function.
- The rest array behaves like any other array inside the function body, supporting
.map,.reduce,.length, etc. - The spread operator (
...arr) is the counterpart used at the call site to expand an array into individual arguments. - Omitting the element type risks an implicit
any[], which defeats the purpose of typing the rest parameter.
Practice what you learned
1. What must the declared type of a rest parameter be?
2. Where must a rest parameter appear in a function's parameter list?
3. Given `function logEvent(eventName: string, ...details: string[]) {}`, how many rest parameters can this function have in total?
4. What is the type of `numbers` inside `function sum(...numbers: number[]) {}`?
5. What is the operator used at a call site to expand an existing array into individual arguments for a rest-parameter function?
Was this page helpful?
You May Also Like
Functions in TypeScript
Learn how TypeScript adds parameter and return type annotations to JavaScript functions for compile-time safety.
Optional and Default Parameters in TypeScript
Make function parameters optional or give them default values, and understand how TypeScript infers their types.
Arrays in TypeScript
How to type homogeneous lists of values using the T[] and Array<T> syntaxes, including multi-dimensional and readonly arrays.
Tuples in TypeScript
Fixed-length, ordered arrays where each position has its own known type — and the classic mutability gotcha to watch for.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics