Let us learn about ‘Functions’ in Typescript

I started learning about Typescript and came across the different ways to play with functions; hence, thought of writing a blog on it summarising the functions topic. As a newcomer to TypeScript, I aim to effectively convey the topic with clarity and precision.

Functions makes the code readable, maintainable, and reusable. It can be used to create layers of abstraction, mimicking classes, information hiding, and modules. In TypeScript, however, we have classes, namespaces, and modules, but functions are still an integral part of the description. Also, TypeScript adds new capabilities to JavaScript functions to make the code better.

Declaring a function

To declare a function in TypeScript, use the 'function' keyword followed by the function name and parameter list. Here's an example:

function greet(name: string): void {
  console.log(`Hello, ${name}!`);
}

This function takes a string parameter called name and logs a greeting to the console. The void return type indicates that the function does not return a value.

Function parameters

Function parameters in TypeScript can have optional and default values, and can also be rest parameters. Here are some examples:

Optional parameters:

function greet(name?: string): void {
  console.log(name ? `Hello, ${name}!` : 'Hello!');
}

This function has an optional name parameter, indicated by the ? after the parameter name. If name is not provided, the function will output a generic greeting.

Default parameters:

function greet(name: string = 'world'): void {
  console.log(`Hello, ${name}!`);
}

This function has a default name parameter, indicated by the = 'world' after the parameter name. If name is not provided, it will default to 'world'.

Rest parameters:

function greetAll(...names: string[]): void {
  for (const name of names) {
    console.log(`Hello, ${name}!`);
  }
}

This function uses a rest parameter to accept an arbitrary number of string arguments. The ... before the parameter name indicates that it is a rest parameter.

Function return types

TypeScript infers the return type of the function, so it doesn't need to be stated either. Although, if the function is large, some developers like to explicitly state the return type for clarity. Functions in TypeScript can have explicit return types, which are indicated after the parameter list and an arrow (=>) symbol. Here's an example:

// Using explicit typing 
const add: Function = (a: number, b: number): number => {
  return a + b;
};

// Inferred typing - TypeScript sees that circle is a function that always returns a string, so no need to explicitly state it
const add = (a: number, b: number) => {
  return a + b;
};

This function takes two numbers and returns their sum, which is indicated by the number return type. Notice how it isn't necessary to explicitly state that 'add' is a function; TypeScript infers it.

Function overloading

Function overloading is a feature in TypeScript that allows you to define multiple function signatures with the same name but different parameter and return types. Here's an example:

function combine(a: string, b: string): string;
function combine(a: number, b: number): number;
function combine(a: any, b: any): any {
  return a + b;
}

This function has two overloaded signatures, one for strings and one for numbers. The final implementation of the function accepts any type of arguments and returns their sum.

Function Signature

If we want to declare a function variable, but not define it (say exactly what it does), then use a function signature. The syntax for a function signature is (parameter: type) => return type, where 'parameter' is the name of the parameter and 'type' is its type, and 'return type' is the type of value that the function returns (if any). Below, the function sayHello must follow the signature after the colon:

// Declare the varible sayHello, and give it a function signature that takes a string and returns nothing.
let sayHello: (name: string) => void;

// Define the function, satisfying its signature
sayHello = (name) => {
  console.log('Hello ' + name);
};

sayHello('Danny'); // Hello Danny

In this example, we are declaring a variable called sayHello and assigning it a function signature that takes a string parameter and returns nothing (or void).

This pattern can be useful when defining interfaces or creating functions that take callbacks as parameters, as it allows you to specify the expected function signature without having to provide a complete implementation at the time of declaration.

Conclusion

Functions are an important part of TypeScript and allow you to write reusable code that can be easily maintained and expanded. By understanding function parameters, return types, and overloading, you can create more robust and flexible code. Thank you for your time.

Happy Learning:)