Master the Art of Typing Functions in TypeScript
Written on
Chapter 1: Understanding Function Typing
In this guide, we will delve into the intricacies of typing functions in TypeScript. With a plethora of function syntaxes available in JavaScript, it can often become perplexing. The aim of this tutorial is to clarify how to effectively type these functions using TypeScript. Let's dive in!
Function Declarations
To declare a function that adds two numbers, you can use the following syntax:
function addNumbers(x: number, y: number): number {
return x + y;
}
Function Expressions
Named Function Expression
You can also define a function expression by naming it:
let addNumbers = function addNumbers(x: number, y: number): number {
return x + y;
};
Anonymous Function Expression
Alternatively, you can create an anonymous function:
let addNumbers = function(x: number, y: number): number {
return x + y;
};
Arrow Functions
Using explicit return for arrow functions:
let addNumbers = (x: number, y: number): number => {
return x + y;
};
Using implicit return for arrow functions can simplify your code:
let addNumbers = (x: number, y: number): number => x + y;
For returning an object implicitly:
let addNumbers = (x: number, y: number): { total: number } => ({ total: x + y });
In this example, parentheses clarify the function's structure.
Type Annotation
You can also apply type annotations to arrow functions:
let addNumbers: (x: number, y: number) => number = (x, y) => x + y;
Type Alias
Using type aliases enhances code readability:
type TAddNumbers = (x: number, y: number) => number;
let addNumbers: TAddNumbers = (x, y) => x + y;
Interfaces
Interfaces can also define function types:
interface IAddNumbers {
addNumbers: (x: number, y: number) => number;
}
let addNumbers: IAddNumbers["addNumbers"] = (x, y) => x + y;
console.log(addNumbers(3, 6));
Another approach using interfaces:
interface IAddNumbers {
(x: number, y: number): number;
}
let addNumbers: IAddNumbers = (x, y) => x + y;
console.log(addNumbers(3, 6));
Optional and Default Parameters
Optional Parameters
In TypeScript, you can define optional parameters:
let addNumbers = (x: number, y?: number) => x + (y ?? 0);
console.log(addNumbers(3)); // 3
console.log(addNumbers(3, 6)); // 9
Default Parameters
Default parameters can also be utilized:
let addNumbers = (x: number, y: number = 5) => x + y;
console.log(addNumbers(3)); // 8
console.log(addNumbers(3, 6)); // 9
console.log(addNumbers(3, undefined)); // 8
If you appreciate this content, your support would mean a lot! 👏
Rest Parameters
Rest parameters allow you to accept an indefinite number of arguments:
let addNumbers = (x: number = 0, ...rest: number[]): number => {
return rest.reduce((acc, curr) => acc + curr, x);
};
console.log(addNumbers(3, 6, 7, 8, 10)); // 34
console.log(addNumbers(undefined, 6, 7, 8, 10)); // 31
Type Extraction
You can extract the type as follows:
type TAddNumbers = (x?: number, ...rest: number[]) => number;
let addNumbers: TAddNumbers = (x = 5, ...rest) => {
return rest.reduce((acc, curr) => acc + curr, x);
};
console.log(addNumbers(3, 6, 7, 8, 10)); // 34
console.log(addNumbers(undefined, 6, 7, 8, 10)); // 36
Methods for Object Properties
Function Declaration as Object Property
You can define methods directly within an object:
const person = {
greeting(name: string): string {
return Hello, my name is ${name};}
};
console.log(person.greeting("Cihan")); // Hello, my name is Cihan
Arrow Function Expression
You can also use arrow function expressions:
const person = {
greeting: (name: string): string => {
return Hello, my name is ${name};}
};
console.log(person.greeting("Cihan")); // Hello, my name is Cihan
If the object has string keys and values, specify the type accordingly:
const person: { dogName: string; greeting(name: string): string } = {
dogName: "Oscar",
greeting(name) {
return My name is ${name} and this is my dog ${this.dogName};}
};
console.log(person.dogName);
console.log(person.greeting("Cihan"));
Using Type Alias
You can also use a type alias:
type TPerson = {
dogName: string;
greeting(name: string): string;
};
const person: TPerson = {
dogName: "Oscar",
greeting(name) {
return My name is ${name} and this is my dog ${this.dogName};}
};
console.log(person.dogName);
console.log(person.greeting("Cihan"));
Methods for Classes
Regular Method in Class
Define a method within a class body like this:
class Person {
greeting(name: string): string {
return Hello, my name is ${name};}
}
const person = new Person();
console.log(person.greeting("Cihan")); // Hello, my name is Cihan
Arrow Function as Class Field
You can also define methods as class fields:
class Person {
greeting = (name: string): string => {
return Hello, my name is ${name};}
}
const person = new Person();
console.log(person.greeting("Cihan")); // Hello, my name is Cihan
Async Functions
Creating an asynchronous function in TypeScript is similar to JavaScript:
async function addNumbers(x: number, y: number): Promise<number> {
return x + y;
}
Async Arrow Function
You can also use async with arrow functions:
const addNumbers = async (x: number, y: number): Promise<number> => x + y;
If you have any questions, feel free to ask in the comments!
If you enjoy content like this, your support by clicking the clap 👏 button would be greatly appreciated. Thank you for encouraging me to write more!
Want to Connect?
- [Linkedin](#)
- [Twitter](#)
- [Github](#)