Functions in TypeScript
Learn how to use Functions in TypeScript with this detailed tutorial. Includes basic and advanced examples to help you master Functions.
Introduction
Functions are the fundamental building blocks in JavaScript and TypeScript. They allow you to encapsulate logic, create reusable code, and define APIs. TypeScript enhances functions by allowing you to define types for parameters and return values.
Basic Examples
Here are some basic examples of using Functions in TypeScript:
Function Declarations
You can define a function in TypeScript with typed parameters and a typed return value.
function add(x: number, y: number): number {
return x + y;
}
console.log(add(2, 3)); // 5
Function Expressions
Functions can also be defined using function expressions.
let myAdd = function(x: number, y: number): number {
return x + y;
};
console.log(myAdd(2, 3)); // 5
Optional and Default Parameters
Parameters can be made optional by using the ?
symbol, and default values can be provided.
function buildName(firstName: string, lastName?: string): string {
if (lastName) return firstName + " " + lastName;
else return firstName;
}
console.log(buildName("Bob")); // Bob
console.log(buildName("Bob", "Smith")); // Bob Smith
function buildNameWithDefault(firstName: string, lastName: string = "Smith"): string {
return firstName + " " + lastName;
}
console.log(buildNameWithDefault("Bob")); // Bob Smith
console.log(buildNameWithDefault("Bob", "Johnson")); // Bob Johnson
Rest Parameters
You can use rest parameters to accept multiple arguments.
function buildName(firstName: string, ...restOfName: string[]): string {
return firstName + " " + restOfName.join(" ");
}
console.log(buildName("Joseph", "Samuel", "Lucas", "MacKinzie")); // Joseph Samuel Lucas MacKinzie
Overloads
Function overloads allow you to define multiple signatures for a function.
function pickCard(x: { suit: string; card: number; }[]): number;
function pickCard(x: number): { suit: string; card: number; };
function pickCard(x: any): any {
if (typeof x == "object") {
return Math.floor(Math.random() * x.length);
} else if (typeof x == "number") {
let suits = ["hearts", "spades", "clubs", "diamonds"];
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
let myDeck = [
{ suit: "diamonds", card: 2 },
{ suit: "spades", card: 10 },
{ suit: "hearts", card: 4 }
];
let pickedCard1 = myDeck[pickCard(myDeck)];
console.log("card: " + pickedCard1.card + " of " + pickedCard1.suit);
let pickedCard2 = pickCard(15);
console.log("card: " + pickedCard2.card + " of " + pickedCard2.suit);
Advanced Examples
Here are some advanced examples of using Functions in TypeScript:
This Parameters
You can explicitly indicate that a method does not use the class instance using this
.
class Deck {
suits = ["hearts", "spades", "clubs", "diamonds"];
cards = Array(52);
createCardPicker(this: Deck) {
return () => {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);
return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
};
}
}
let deck = new Deck();
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
console.log("card: " + pickedCard.card + " of " + pickedCard.suit);
Function Types
You can define function types and use them as types for variables.
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
let result = src.search(sub);
return result > -1;
}
console.log(mySearch("Hello, world", "world")); // true
console.log(mySearch("Hello, world", "foo")); // false
Generic Functions
You can use generics to create functions that work with different types.
function identity(arg: T): T {
return arg;
}
let output1 = identity("myString"); // output1 is of type string
let output2 = identity(42); // output2 is of type number
Constraints on Generics
You can impose constraints on generic types to limit the types they accept.
interface Lengthwise {
length: number;
}
function loggingIdentity(arg: T): T {
console.log(arg.length);
return arg;
}
loggingIdentity({ length: 10, value: 3 });
Using Class Types in Generics
You can use class types in generics to create more flexible and reusable components.
function create(c: { new(): T }): T {
return new c();
}
class BeeKeeper {
hasMask: boolean = true;
}
class ZooKeeper {
nametag: string = "Mikle";
}
class Animal {
numLegs: number = 4;
}
class Bee extends Animal {
keeper: BeeKeeper = new BeeKeeper();
}
class Lion extends Animal {
keeper: ZooKeeper = new ZooKeeper();
}
function createInstance(c: new () => A): A {
return new c();
}
createInstance(Lion).keeper.nametag; // typechecks!
createInstance(Bee).keeper.hasMask; // typechecks!
Function Overloads
Function overloads allow you to provide multiple function signatures for a single function.
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === "number") {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === "string") {
return x.split('').reverse().join('');
}
}
console.log(reverse(12345)); // 54321
console.log(reverse("hello")); // olleh
Arrow Functions
Arrow functions provide a shorter syntax for writing functions and do not have their own this
context.
let sum = (x: number, y: number): number => {
return x + y;
};
console.log(sum(2, 3)); // 5
Conclusion
Functions in TypeScript provide a powerful way to encapsulate logic, create reusable code, and define APIs. By using typed parameters and return values, you can catch errors early and improve the readability and maintainability of your code. Whether you are working on a small project or a large-scale application, mastering functions in TypeScript will help you write more reliable and efficient code.