- TypeScript Tutorial
- TypeScript Home
- TypeScript Introduction
- TypeScript Setup
- TypeScript First Program
- TypeScript vs JavaScript
- TypeScript Data Types
- TypeScript Type Inference
- TypeScript Type Annotations
- TypeScript Interfaces
- TypeScript Enums
- TypeScript Type Aliases
- TypeScript Type Assertions
- TypeScript Variables
- TypeScript Functions
- TypeScript Functions
- TypeScript Optional Parameters
- TypeScript Default Parameters
- TypeScript Rest Parameters
- TypeScript Arrow Functions
- Classes and Objects
- Introduction to Classes
- Properties and Methods
- Access Modifiers
- Static Members
- Inheritance
- Abstract Classes
- Interfaces vs Classes
- Advanced Types
- TypeScript Union Types
- TypeScript Intersection Types
- TypeScript Literal Types
- TypeScript Nullable Types
- TypeScript Type Guards
- TypeScript Discriminated Unions
- TypeScript Index Signatures
- TypeScript Generics
- Introduction to Generics
- TypeScript Generic Functions
- TypeScript Generic Classes
- TypeScript Generic Constraints
- TypeScript Modules
- Introduction to Modules
- TypeScript Import and Export
- TypeScript Default Exports
- TypeScript Namespace
- Decorators
- Introduction to Decorators
- TypeScript Class Decorators
- TypeScript Method Decorators
- TypeScript Property Decorators
- TypeScript Parameter Decorators
- Configuration
- TypeScript tsconfig.json File
- TypeScript Compiler Options
- TypeScript Strict Mode
- TypeScript Watch Mode
TypeScript Rest Parameters
In modern development, functions often need to be flexible. You might design a function that handles two arguments today, but needs to handle ten tomorrow. Instead of manually defining every possible argument, TypeScript provides Rest Parameters. This feature allows a function to treat a variable number of arguments as a single, organized array.
Rest parameters are the modern successor to the old JavaScript arguments object. Unlike arguments, rest parameters are true arrays, giving you access to helpful methods like map, filter, and reduce right out of the box. They are identified by three dots (...) placed before the parameter name.
arguments object. However, arguments isn't a real array and doesn't work well with TypeScript's type checking. Always prefer rest parameters for better type safety and cleaner code.
Syntax for Rest Parameters
Defining a rest parameter is straightforward. You place the ellipsis before the name and ensure the type is defined as an array.
function functionName(...parameterName: type[]): returnType {
// The parameterName is available here as an array
}
In this syntax:
...parameterName: The ellipsis tells TypeScript to collect all remaining arguments into this variable.type[]: This is crucial. Since rest parameters collect multiple values, their type must always be an array (e.g.,string[],number[], or a custom interface array).
users, tags, or prices) to signal to other developers that the variable contains a collection.
Example of Rest Parameters
A classic use case for rest parameters is a mathematical utility, such as a function that sums an unknown amount of numbers:
function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(10, 20)); // Output: 30
console.log(sum(1, 2, 3, 4, 5)); // Output: 15
console.log(sum()); // Output: 0
In this example, the sum function is highly reusable. It doesn't matter if you pass two numbers or twenty; TypeScript treats numbers as a number[], allowing us to use the .reduce() method to calculate the total cleanly.
sum() returns 0 because the array is empty, not undefined.
Using Rest Parameters with Other Parameters
You can mix regular parameters with rest parameters. This is common when the first few arguments are required or specific, and the rest are optional extras.
function buildUserCard(firstName: string, lastName: string, ...hobbies: string[]): string {
return `${firstName} ${lastName} enjoys: ${hobbies.join(", ")}`;
}
console.log(buildUserCard("Alice", "Smith", "Hiking", "Reading", "Photography"));
// Output: "Alice Smith enjoys: Hiking, Reading, Photography"
// This will cause an error:
function errorFunc(...items: string[], name: string) { ... }
Rest Parameters with Different Types
Sometimes your function needs to accept a "grab bag" of different data types. You can use TypeScript Union Types within the rest parameter to maintain type safety while staying flexible.
function logEvent(timestamp: number, ...metadata: (string | boolean)[]): void {
console.log(`Event at ${timestamp}:`, metadata);
}
logEvent(1625097600, "User Login", true, "Mobile App");
// Output: Event at 1625097600: ["User Login", true, "Mobile App"]
In this scenario, the metadata array is strictly allowed to contain only strings or booleans, preventing accidental bugs if a number or object were passed by mistake.
Rest Parameters with Spread Syntax
Rest parameters and the Spread Syntax are two sides of the same coin. While rest parameters collect items into an array, spread syntax unpacks an array into individual arguments. This is incredibly useful when you have an existing data set you want to pass into a flexible function.
function sendNotification(...users: string[]): void {
users.forEach(user => console.log(`Notification sent to ${user}`));
}
const activeUsers = ["John", "Sarah", "Mike"];
// Using spread syntax to pass the array elements as individual arguments
sendNotification(...activeUsers);
Without the spread syntax (...activeUsers), you would have to pass each array index manually (activeUsers[0], activeUsers[1]...), which is inefficient and error-prone.
Summary
Rest parameters are an essential tool for creating flexible, type-safe functions in TypeScript. By using the ... syntax, you can capture any number of arguments into a single array, making your code easier to read and maintain.
- Flexibility: Handle any number of arguments without over-complicating function signatures.
- Type Safety: Ensure that all collected arguments conform to a specific type or union of types.
- Native Array Methods: Immediately use
map,sort, orreduceon your arguments. - Compatibility: Combine them with standard parameters, provided the rest parameter comes last.
Whether you are building a logging utility, a math library, or a UI component that accepts various styling flags, rest parameters provide the cleanest path to dynamic argument handling.