Optional, Default, and Rest Parameters in TypeScript

Table of Contents

  • Introduction
  • Optional Parameters
    • Syntax for Optional Parameters
    • Use Cases for Optional Parameters
  • Default Parameters
    • Syntax for Default Parameters
    • Use Cases for Default Parameters
  • Rest Parameters
    • Syntax for Rest Parameters
    • Use Cases for Rest Parameters
  • Combining Optional, Default, and Rest Parameters
  • Practical Examples
  • Conclusion

Introduction

Functions in TypeScript are a powerful way to define reusable code blocks. One of the most useful features TypeScript offers is the ability to add flexibility to function signatures through optional, default, and rest parameters. These features allow developers to create functions that can handle various numbers of arguments without overloading them with excessive logic.

In this article, we will dive deep into optional, default, and rest parameters, exploring their syntax, practical use cases, and best practices for each. By the end of this article, you’ll understand how to make your functions more versatile and easier to maintain.


Optional Parameters

Optional parameters allow you to define parameters that may or may not be passed into the function. This is helpful when you have a function that doesn’t always require all arguments but still wants to handle cases where they might be provided.

Syntax for Optional Parameters

In TypeScript, you mark a parameter as optional by adding a question mark (?) after the parameter’s name in the function signature.

function greet(name: string, age?: number): string {
if (age) {
return `Hello ${name}, you are ${age} years old.`;
} else {
return `Hello ${name}!`;
}
}

In this example:

  • The age parameter is optional. The function can be called with or without the age parameter.
  • If age is provided, it is included in the returned greeting; if not, a default greeting without age is returned.

Use Cases for Optional Parameters

  1. Flexible Function Signatures: Optional parameters are ideal when you have functions that may not always need all arguments, like in the greet example above.
  2. Backward Compatibility: When you are modifying an existing function and want to add new functionality but don’t want to break existing code, optional parameters are an excellent way to maintain compatibility.

Default Parameters

Default parameters allow you to specify default values for parameters that are not passed. This means that if the caller doesn’t provide a value for a parameter, the default value is used instead.

Syntax for Default Parameters

You define default parameters by assigning a default value in the function signature.

function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}

In this example:

  • The greeting parameter has a default value of "Hello".
  • If the caller doesn’t provide a greeting, it defaults to "Hello".

Use Cases for Default Parameters

  1. Fallback Values: Default parameters are ideal when you want to ensure that a function always has a valid value for a parameter, even if the caller omits it.
  2. Simplifying Function Calls: By providing default values, you simplify the function call and reduce the need for additional checks inside the function.

Rest Parameters

Rest parameters allow you to pass an arbitrary number of arguments into a function. These parameters are collected into an array, and you can iterate over them or perform operations on the entire group of arguments.

Syntax for Rest Parameters

Rest parameters are defined using the ellipsis (...) syntax before the parameter name. It must be the last parameter in the function signature.

function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}

In this example:

  • The numbers parameter is a rest parameter, which allows the function to accept any number of number arguments.
  • The function uses the reduce() method to sum all the numbers in the array.

Use Cases for Rest Parameters

  1. Variable Number of Arguments: Rest parameters are useful when you don’t know how many arguments will be passed to the function. It allows for flexible function calls with a dynamic number of inputs.
  2. Aggregating Data: Functions like sum, average, or concatenate are often good candidates for rest parameters, as they need to handle a variable amount of data.

Combining Optional, Default, and Rest Parameters

You can combine optional, default, and rest parameters in the same function, but there are some rules about the order in which they should be placed in the function signature.

  • Rest parameters must be the last parameter.
  • Optional parameters should be placed before rest parameters, as they can either be provided or omitted.
  • Default parameters should be placed before optional or rest parameters because the default value is assigned when the parameter is not passed.

Example of Combined Parameters

function createUser(username: string, email: string, age?: number, isActive: boolean = true, ...roles: string[]): string {
return `${username} (${email}) is ${age ? age : "not provided"} years old, active: ${isActive}, roles: ${roles.join(", ")}`;
}

In this function:

  • username and email are required parameters.
  • age is optional.
  • isActive has a default value of true.
  • roles is a rest parameter, allowing multiple roles to be passed in.

Key Considerations:

  • Optional parameters are useful for flexibility in the arguments a function can accept.
  • Default parameters are ideal when you want to ensure a parameter has a value, even if the caller doesn’t provide it.
  • Rest parameters allow you to handle a variable number of arguments, making your functions highly flexible.

Practical Examples

Example 1: Logging Function

function logMessage(level: string, message: string, timestamp: Date = new Date(), ...tags: string[]): void {
console.log(`[${timestamp.toISOString()}] [${level}] ${message} ${tags.length ? `Tags: ${tags.join(", ")}` : ""}`);
}

logMessage("INFO", "System started", new Date(), "startup", "init"); // With tags
logMessage("ERROR", "An error occurred"); // Without tags

In this example:

  • level and message are required parameters.
  • timestamp has a default value of new Date().
  • tags is a rest parameter, allowing any number of tags to be passed in.

Example 2: Customizing Reports

function generateReport(title: string, date: string, description: string = "No description provided", ...categories: string[]): string {
return `${title} (${date}) - ${description}. Categories: ${categories.join(", ")}`;
}

generateReport("Monthly Report", "2025-04-30", "Detailed financial report", "Finance", "Quarterly"); // With categories
generateReport("Daily Report", "2025-04-30"); // Without description and categories

In this case:

  • description has a default value.
  • categories is a rest parameter, allowing any number of categories to be provided.

Conclusion

Understanding how to use optional, default, and rest parameters is crucial for writing flexible and maintainable functions in TypeScript. By incorporating these features, you can handle various argument configurations without creating multiple function signatures or using unnecessary logic.

To summarize:

  • Optional Parameters provide flexibility by allowing certain arguments to be omitted.
  • Default Parameters provide fallback values for parameters not passed by the caller.
  • Rest Parameters allow you to handle a dynamic number of arguments.

By mastering these parameter types, you can create more robust and scalable TypeScript applications.