Working with the DOM

Learn how to use TypeScript to interact with the DOM and create dynamic web pages.


TypeScript Functions for Beginners

What are Functions in TypeScript?

Functions are reusable blocks of code that perform a specific task. Think of them like mini-programs within your larger program. They take in some input (called arguments or parameters), do something with that input, and then often return a result. TypeScript, being a superset of JavaScript, supports all of JavaScript's function capabilities, but adds static typing to them, making your code more robust and easier to understand.

Why Use Functions?

  • Reusability: Write code once, use it many times.
  • Modularity: Break down complex problems into smaller, manageable parts.
  • Readability: Make your code easier to understand and maintain.

Exploring Function Types, Parameters, and Return Types

Basic Function Declaration

Let's start with a simple function that adds two numbers:

 function add(a: number, b: number): number {
        return a + b;
      }

      let sum: number = add(5, 3); // sum will be 8
      console.log(sum); 

Explanation:

  • function add(a: number, b: number): number { ... } declares a function named add.
  • a: number and b: number specify that the function expects two parameters, a and b, both of which must be of type number. This is TypeScript's static typing in action.
  • : number after the parameter list indicates that the function is expected to return a value of type number.
  • return a + b; performs the addition and returns the result.

Parameters

Required Parameters

By default, TypeScript expects the correct number of arguments to be provided to a function.

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

      console.log(greet("Alice")); // Output: Hello, Alice!
      // console.log(greet()); // Error: Expected 1 arguments, but got 0. 

Optional Parameters

You can make parameters optional by adding a ? after the parameter name. Optional parameters must come after required parameters.

 function greetOptional(name: string, greeting?: string): string {
        if (greeting) {
          return `${greeting}, ${name}!`;
        } else {
          return `Hello, ${name}!`;
        }
      }

      console.log(greetOptional("Bob", "Good morning")); // Output: Good morning, Bob!
      console.log(greetOptional("Bob")); // Output: Hello, Bob! 

Default Parameters

You can also provide default values for parameters. If an argument isn't provided for a parameter with a default value, the default value will be used.

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

      console.log(greetDefault("Charlie", "Hi")); // Output: Hi, Charlie!
      console.log(greetDefault("Charlie")); // Output: Hello, Charlie! 

Rest Parameters

Rest parameters allow you to pass an indefinite number of arguments to a function as an array. They are denoted by three dots (...) before the parameter name. They must be the last parameter.

 function sumAll(...numbers: number[]): number {
        let total = 0;
        for (const number of numbers) {
          total += number;
        }
        return total;
      }

      console.log(sumAll(1, 2, 3)); // Output: 6
      console.log(sumAll(1, 2, 3, 4, 5)); // Output: 15 

Here, numbers is an array of numbers.

Return Types

As we saw earlier, you can specify the return type of a function after the parameter list, using a colon (:) followed by the type. If a function doesn't return anything, you can use the void type.

 function logMessage(message: string): void {
        console.log(message);
        // No return statement needed
      }

      logMessage("This is a message."); 

Function Overloading

Function overloading allows you to define multiple function signatures for the same function name. This lets you provide different parameter types and/or return types, depending on how the function is called. TypeScript uses the best match based on the arguments provided. You provide the different function signatures *before* the function implementation.

 // Overload signatures
      function add(a: number, b: number): number;
      function add(a: string, b: string): string;

      // Implementation signature
      function add(a: any, b: any): any {
        return a + b;
      }

      console.log(add(1, 2)); // Output: 3 (number)
      console.log(add("Hello", " World")); // Output: Hello World (string)
      // console.log(add(1, "World")); // Error: No overload matches this call. 

Explanation:

  • We declare two separate function signatures for add, one that takes two numbers and returns a number, and another that takes two strings and returns a string.
  • The final function add(a: any, b: any): any provides the actual implementation of the function. Note that the parameter types here are wider than the types declared in the overload signatures (using `any`). This is because this implementation needs to handle *all* possible calls matching the overloads.
  • TypeScript uses the overload signatures to determine the correct return type based on the arguments passed to the function.
  • It's crucial that the implementation signature can handle all potential parameter types defined in the overload signatures.