Functions in TypeScript

Functions in TypeScript

This article explains functions in TypeScript.

YouTube Video

Functions in TypeScript

Functions in TypeScript are JavaScript functions with added type annotations. In TypeScript, you can write more robust code by clearly defining the types of inputs (parameters) and outputs (return values) for functions. Below, we introduce the basic methods for defining functions and some characteristics of functions in TypeScript.

Basic Function Definition

1function add(x: number, y: number): number {
2    return x + y;
3}
4
5console.log(add(5, 10));  // 15
  • The add function takes two arguments of type number and returns a value of type number.
  • It takes two arguments, x and y, both of type number, with their types explicitly specified.
  • The return type is also specified as : number.

Anonymous Functions (Function Expressions)

Anonymous functions and function expressions can also be used in TypeScript. Types can be annotated in the same way.

1const multiply = function (x: number, y: number): number {
2    return x * y;
3};
4
5console.log(multiply(3, 4));  // 12
  • You can assign an anonymous function to a variable and call it later.
1const factorial = function fact(n: number): number {
2  if (n <= 1) return 1;
3  return n * fact(n - 1); // Can call itself recursively
4};
5
6console.log(factorial(5)); // 120
  • You can use a named function expression to enable recursive calls.

Arrow Functions

Type annotations can be used with arrow functions as well.

1const subtract = (x: number, y: number): number => {
2    return x - y;
3};
4
5console.log(subtract(10, 4));  // 6

This code defines an arrow function subtract with type annotations that takes two numbers as arguments and returns their difference.

Optional and Default Parameters

Parameters can be made optional or given default values.

Optional Parameters

Adding ? after the parameter name makes it optional.

1function greet(name?: string): string {
2    return name ? `Hello, ${name}` : "Hello!";
3}
4
5console.log(greet());        // Hello!
6console.log(greet("Alice"));  // Hello, Alice

This code accepts an optional argument; if the argument is provided, it greets using the name, otherwise it returns a generic greeting.

Default Parameters

You can also set default values for parameters.

1function greetWithDefault(name: string = "Guest"): string {
2    return `Hello, ${name}`;
3}
4
5console.log(greetWithDefault());         // Hello, Guest
6console.log(greetWithDefault("Bob"));    // Hello, Bob

This function uses "Guest" as the default value if no argument is passed, and greets using the specified or default name.

Function Type Definition

It is also possible to define the type of the function itself. For example, this is used when passing a function as an argument.

1type Operation = (x: number, y: number) => number;
2
3const addOperation: Operation = (x, y) => x + y;
4const multiplyOperation: Operation = (x, y) => x * y;
5
6console.log(addOperation(2, 3));      // 5
7console.log(multiplyOperation(2, 3)); // 6

This code defines a function type Operation that takes two numbers and returns a number, then uses it to create and run addition and multiplication functions.

When There Is No Return Value (void type)

For functions with no return value, specify the void type.

1function logMessage(message: string): void {
2    console.log(message);
3}
4
5logMessage("This is a message.");  // This is a message.

This code defines a void function logMessage that takes a string message and prints it to the console without returning a value.

Callback Function

Passing a function as an argument to another function and having it executed later is called a callback function. It is frequently used in asynchronous processing and event handling.

1function processData(callback: (data: string) => void): void {
2    const data: string = "Processed Data";
3    callback(data);
4}
5
6processData((result: string): void => {
7    console.log(result);
8});

In this example, a function that outputs a value to the console is passed as a callback function.

Alternatively, you can define a callback type using type or interface.

 1type Callback = (data: string) => void;
 2
 3function processData(callback: Callback): void {
 4    const data: string = "Processed Data";
 5    callback(data);
 6}
 7
 8processData((result: string): void => {
 9    console.log(result);
10});

Defining a callback type using type or interface improves reusability.

Function Overloading

Function overloading allows you to define functions with the same name but different parameter lists. In TypeScript, you can define multiple functions with the same name and perform different operations based on the types and numbers of parameters.

 1// Overload Signature
 2function double(value: number): number;
 3function double(value: string): string;
 4
 5// Implementation Signature
 6function double(value: number | string): number | string {
 7    if (typeof value === "number") {
 8        return value * 2;
 9    } else if (typeof value === "string") {
10        return value + value;
11    }
12}
13
14console.log(double(10));      // 20
15console.log(double("Hello")); // HelloHello

In TypeScript, overloading is achieved as follows:.

  • Overload Signature

    • Defines how the function can be used (its signature). By writing this multiple times, overloading becomes possible.
  • Implementation Signature

    • Implements the actual function body. This part is defined only once and handles all cases declared in the overload signatures.

Rules for Overloading

The following rules apply to function overloading:.

  • Order of Overload Signature Definitions

    • Since evaluation occurs from top to bottom, it is recommended to define specific types first, followed by more generic types.
  • Compatibility of the Implementation Signature

    • The implementation signature must be compatible with the arguments and return values of all overload signatures.
  • Specify Details in Overload Signatures

    • The implementation signature tends to be ambiguous, so details should be specified in the overload signatures.
    • If only the implementation signature is defined, the type inference for the function will be insufficient.

Summary

Functions in TypeScript have the following characteristics.

  • Type Annotations
    • By specifying types for arguments and return values, you can write safer code.
  • Anonymous Functions and Arrow Functions
    • They can be used just like in JavaScript, and adding type annotations improves type safety.
  • Optional and Default Parameters
    • You can make argument specification more flexible as needed.
  • Function Type Definitions
    • Define the type of the function itself to perform type checking.
  • Function Overloading
    • You can support different arguments with the same function name.

By utilizing these, you can write clearer and more robust code in TypeScript.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video