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 typenumber
and returns a value of typenumber
. - It takes two arguments,
x
andy
, both of typenumber
, 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.