Day 43: Generics
Dharan Ganesan
Posted on September 7, 2023
we'll dive into TypeScript generics, exploring what they are, why you should use them, and how to wield their full potential. Let's get started! 🏊♂️
What Are TypeScript Generics?
At its core, TypeScript generics provide a way to create reusable, type-safe components. They allow you to write functions, classes, and interfaces without committing to a specific data type. Instead, you can use placeholders (typically represented by T
, U
, or other descriptive names) that get replaced with actual types when you use the generic component.
function identity<T>(arg: T): T {
return arg;
}
T
is a generic type parameter. When you call identity(42)
, TypeScript infers that T
should be number
. When you call identity("Hello")
, T
becomes string
. Neat, right? 😎
Why Use TypeScript Generics?
Type Safety: Generics ensure that your code is type-safe. They catch type-related errors at compile-time, saving you from runtime headaches.
Reusability: Generics promote code reuse. You can create functions and classes that work with a wide range of types, reducing duplication.
Flexibility: Generics give you the flexibility to work with different data structures without sacrificing type safety. Think arrays, linked lists, trees, or custom data structures.
IDE Support: TypeScript's IDE support is top-notch. With generics, your code editor can provide intelligent suggestions and autocompletions.
How to Use TypeScript Generics
Functions
function reverseArray<T>(arr: T[]): T[] {
return arr.reverse();
}
You can call this function with any array type.
const numbers = [1, 2, 3];
const reversedNumbers = reverseArray(numbers);
const fruits = ["apple", "banana", "cherry"];
const reversedFruits = reverseArray(fruits);
Classes
Generics are not limited to functions. You can use them with classes too. Imagine creating a Stack
class:
class Stack<T> {
private elements: T[] = [];
push(item: T) {
this.elements.push(item);
}
pop(): T | undefined {
return this.elements.pop();
}
}
This Stack
class can work with any data type:
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
const poppedNumber = numberStack.pop();
const stringStack = new Stack<string>();
stringStack.push("hello");
stringStack.push("world");
const poppedString = stringStack.pop();
Constraints
Sometimes you want to narrow down the types you can use with generics. You can do this using constraints. For example, you might want to create a function that works only with objects that have a length
property.
function getLength<T extends { length: number }>(obj: T): number {
return obj.length;
}
Now, you can't use getLength
with just any type; it must have a length
property.
const array = [1, 2, 3];
getLength(array); // Works
const str = "Hello";
getLength(str); // Works
const num = 42;
getLength(num); // Error: 'length' does not exist on type 'number'
Posted on September 7, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.