How does TypeScript support optional parameters in function?


TypeScript is a statically typed superset of JavaScript that adds static typing capabilities to the language. One of the key features of TypeScript is its ability to provide optional parameters in function declarations, allowing developers to define functions with parameters that may or may not be provided during function calls. This flexibility enhances code reusability and simplifies function invocations, leading to more maintainable and expressive code.

In this tutorial, we will explore how TypeScript supports optional parameters in functions, covering the syntax, benefits, and some practical examples.

Syntax

To define optional parameters in TypeScript functions, you can use the question mark (?) symbol after the parameter name in the function declaration. This indicates that the parameter is optional and can be omitted when calling the function. The general syntax for a function with optional parameters is as follows −

function functionName(param1: type, param2?: type) {
   // Function body
}

In the syntax above, param1 is a required parameter, whereas param2 is an optional parameter. The question mark indicates that param2 is not mandatory and can be omitted when invoking the function. Optional parameters can only be placed at the end of the parameter list.

Benefits of Optional Parameters

  • Flexibility − Optional parameters provide flexibility in function calls by allowing developers to omit certain arguments when invoking a function. This can be useful in scenarios where a parameter may not always be necessary, leading to cleaner and more concise code.

  • Code Reusability − Optional parameters enable the creation of functions that can be reused in multiple contexts. By making parameters optional, developers can define generic functions that accommodate various use cases without requiring separate functions for each specific case.

  • Improved Readability − Optional parameters can enhance code readability by clearly indicating which arguments are mandatory and which ones are optional. This allows developers to understand the intended usage of a function more easily and makes the code more self-explanatory.

Examples

Example 1: Basic Optional Parameter

In the example below, the greet function has an optional parameter greeting. If a greeting is provided during function invocation, it will be included in the output. If a greeting is omitted, a default greeting will be used.

function greet(name: string, greeting?: string) {
   if (greeting) {
      console.log(`${greeting}, ${name}!`);
   } else {
      console.log(`Hello, ${name}!`);
   }
}
greet("Alice");  // Output: Hello, Alice!
greet("Bob", "Hi");  // Output: Hi, Bob!

On compiling, it will generate the following JavaScript code −

function greet(name, greeting) {
   if (greeting) {
      console.log("".concat(greeting, ", ").concat(name, "!"));
   }
   else {
      console.log("Hello, ".concat(name, "!"));
   }
}
greet("Alice"); // Output: Hello, Alice!
greet("Bob", "Hi"); // Output: Hi, Bob!

Output

The above code will produce the following output −

Hello, Alice!
Hi, Bob!

Example 2: Optional Parameters With Default Values

In this example, the calculateArea function has two parameters, width and height. The height parameter is optional and has a default value of 10. If the height is not provided during the function call, it will default to 10.

function calculateArea(width: number, height: number = 10) {
   return width * height;
}

console.log(`The area with 5 input is: ${calculateArea(5)}`); 
console.log(`The area with 5, 8 input is: ${calculateArea(5, 8)}`);

On compiling, it will generate the following JavaScript code −

function calculateArea(width, height) {
   if (height === void 0) { height = 10; }
   return width * height;
}
console.log("The area with 5 input is: ".concat(calculateArea(5)));
console.log("The area with 5, 8 input is: ".concat(calculateArea(5, 8)));

Output

The area with 5 input is: 50
The area with 5, 8 input is: 40

Example 3: Optional Parameters in Callback Function

In this example, the fetchData function accepts a callback function as an optional parameter. The fetchData method is defined to simulate the process of fetching data from a given URL. The callback function can be invoked with or without an error parameter depending on whether an error occurred during the data fetch operation.

function fetchData(url: string, callback: (data: any, error?: Error) => void) {
   // Simulating data fetching from the URL
   const data = { id: 1, name: "John Doe" };
   // Invoke the callback function with the fetched data
   callback(data);
   // Simulating the presence of an error
   const error = new Error("Oh an error occurred!");
   callback(data, error);
}
// Example usage:
fetchData("https://example.com/data", (data, error) => {
   if (error) {
      console.error("An error occurred:", error);
   } else {
      console.log("Fetched data:", data, "

"); } });

On compiling, it will generate the following JavaScript code −

function fetchData(url, callback) {
   // Simulating data fetching from the URL
   var data = { id: 1, name: "John Doe" };
   // Invoke the callback function with the fetched data
   callback(data);
   // Simulating the presence of an error
   var error = new Error("Oh an error occurred!");
   callback(data, error);
}
// Example usage:
fetchData("https://example.com/data", function (data, error) {
   if (error) {
      console.error("An error occurred:", error);
   }
   else {
      console.log("Fetched data:", data, "

"); } });

Output

Fetched data: { id: 1, name: 'John Doe' } 

An error occurred: Error: Oh an error occurred!
   at fetchData (/home/cg/root/6477262d95bb2/main.js:7:17)
   at Object.<anonymous> (/home/cg/root/6477262d95bb2/main.js:11:1)
   at Module._compile (internal/modules/cjs/loader.js:999:30)
   at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
   at Module.load (internal/modules/cjs/loader.js:863:32)
   at Function.Module._load (internal/modules/cjs/loader.js:708:14)
   at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
   at internal/main/run_main_module.js:17:47

The second call with the error parameter results in an error in the terminal, as expected.

Example 4: Optional Object Properties

In this example, the Person interface has optional properties such as age and email. The displayPerson function can handle objects that conform to the Person interface, regardless of whether the optional properties are present or not.

interface Person {
   name: string;
   age?: number;
   email?: string;
}

function displayPerson(person: Person) {
   console.log(`Name: ${person.name}`);
   if (person.age) {
      console.log(`Age: ${person.age}`);
   }
   if (person.email) {
      console.log(`Email: ${person.email}`);
   }
}

const alice: Person = { name: "Alice" };
const bob: Person = { name: "Bob", age: 25, email: "bob@example.com" };

displayPerson(alice);
displayPerson(bob);

On compiling, it will generate the following JavaScript code −

function displayPerson(person) {
   console.log("Name: ".concat(person.name));
   if (person.age) {
      console.log("Age: ".concat(person.age));
   }
   if (person.email) {
      console.log("Email: ".concat(person.email));
   }
}
var alice = { name: "Alice" };
var bob = { name: "Bob", age: 25, email: "bob@example.com" };
displayPerson(alice);
displayPerson(bob);

Output

Name: Alice
Name: Bob
Age: 25
Email: bob@example.com

Example 5: Optional Parameters in Class Methods

In this example, we have a Rectangle class with a calculateArea method. The calculateArea method has an optional parameter unit which represents the unit of measurement for the area. If units are provided, they will be included in the output. If units are omitted, the default behavior will display the area without any units. This allows for flexible usage of the calculateArea method based on the specific needs of the caller.

class Rectangle {
   private width: number;
   private height: number;

   constructor(width: number, height: number) {
      this.width = width;
      this.height = height;
   }

   calculateArea(units?: string): number {
      const area = this.width * this.height;
      if (units) {
         console.log(`Area: ${area} ${units}`);
      } else {
         console.log(`Area: ${area}`);
      }
      return area;
   }
}

const rectangle1 = new Rectangle(5, 10);
rectangle1.calculateArea();  // Output: Area: 50
rectangle1.calculateArea("sq. units");  // Output: Area: 50 sq. units

On compiling, it will generate the following JavaScript code −

var Rectangle = /** @class */ (function () {
   function Rectangle(width, height) {
      this.width = width;
      this.height = height;
   }
   Rectangle.prototype.calculateArea = function (units) {
      var area = this.width * this.height;
      if (units) {
         console.log("Area: ".concat(area, " ").concat(units));
      }
      else {
         console.log("Area: ".concat(area));
      }
      return area;
   };
   return Rectangle;
}());
var rectangle1 = new Rectangle(5, 10);
rectangle1.calculateArea(); // Output: Area: 50
rectangle1.calculateArea("sq. units"); // Output: Area: 50 sq. units

Output

The above code will produce the following output −

Area: 50
Area: 50 sq. units

Conclusion

TypeScript's support for optional parameters in functions enhances code flexibility, reusability, and readability. By making certain parameters optional, developers can create functions that can be called with or without specific arguments. This feature allows for more concise and adaptable code, making it easier to work with functions in different scenarios. Understanding how to define and use optional parameters in TypeScript can significantly improve your development experience, leading to more maintainable and expressive code.

Updated on: 21-Aug-2023

116 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements