Welcome back! I am Mihir, and in this lesson we will learn rest parameters in TypeScript.
Rest parameters let a function accept any number of arguments.
What is a Rest Parameter?
Use ... before the parameter name.
function printNames(...names: string[]): void {
names.forEach((name) => console.log(name));
}Now you can call:
printNames("Mihir");
printNames("Mihir", "Aarav", "Riya");Inside the function, names is a string[].
Rest Parameters Must Be Arrays
This is the correct type:
function sum(...numbers: number[]): number {
return numbers.reduce((total, number) => total + number, 0);
}Call it like this:
sum(10, 20, 30);Invalid:
sum(10, "20", 30);Every argument must be a number.
Rest Parameter Must Be Last
Rest parameters collect the remaining arguments, so they must come last.
function logMessages(prefix: string, ...messages: string[]): void {
messages.forEach((message) => console.log(`${prefix}: ${message}`));
}This works:
logMessages("INFO", "Started", "Loaded", "Finished");The first argument is prefix. The rest go into messages.
Rest Parameters with Union Types
function printValues(...values: Array<string | number>): void {
values.forEach((value) => console.log(value));
}This accepts strings and numbers:
printValues("id", 101, "score", 95);Invalid:
printValues(true);Boolean is not part of the union.
Rest Parameters with Tuples
You can use tuple types when the remaining arguments have a specific shape.
function createUser(...args: [name: string, age: number]): void {
const [name, age] = args;
console.log(`${name} is ${age} years old`);
}Call:
createUser("Mihir", 25);Invalid:
createUser(25, "Mihir");The tuple order matters.
Rest Parameters vs Spread Syntax
Rest collects arguments:
function sum(...numbers: number[]): number {
return numbers.reduce((total, number) => total + number, 0);
}Spread expands an array:
const scores = [10, 20, 30];
sum(...scores);Same ... symbol, different direction.
Rest Parameters in Callbacks
Rest parameters can be used in function types too.
type Logger = (...messages: string[]) => void;
const logger: Logger = (...messages) => {
messages.forEach((message) => console.log(message));
};This describes a function that accepts any number of string messages.
Common Mistake: Using any[]
Avoid this:
function logEverything(...items: any[]): void {
console.log(items);
}Prefer a safer type:
function logValues(...items: Array<string | number | boolean>): void {
console.log(items);
}Use unknown[] if values are truly unknown and must be checked first.
Quick Reference Summary
| Concept | Example |
|---|---|
| String rest | ...names: string[] |
| Number rest | ...numbers: number[] |
| Must be last | prefix: string, ...items: string[] |
| Union rest | ...(string | number)[] |
| Tuple rest | ...args: [string, number] |
| Function type | (...messages: string[]) => void |
Practice
Create a function that calculates an average:
function average(...scores: number[]): number {
const total = scores.reduce((sum, score) => sum + score, 0);
return total / scores.length;
}
console.log(average(90, 85, 100));Try passing a string and see what TypeScript says.
What You've Learned
You now understand:
- What rest parameters are
- How to type rest parameters as arrays
- Why rest parameters must be last
- How union rest parameters work
- How tuple rest parameters work
- The difference between rest and spread
- How to type rest parameters in function types
What's Next?
In the next lesson, we will learn Function Type Expressions in TypeScript.
We will describe function shapes using reusable types.
Need Help?
- Have questions, confusion, or want to know more? Contact me
Rest parameters are perfect when a function has one job but flexible input length.