21
NovGenerics in TypeScript
Generics in TypeScript are a valuable feature that enables you to write functions, classes, and interfaces that can handle any data type while remaining type-safe. Consider designing a method to handle arrays that can also handle numbers, texts, and even custom objects without having to rewrite the logic for each kind. This is where generics come into play!
So In this TypeScript tutorial, We will gonna see Generics in TypeScript including Example of Generics, Why Use Generics? etc.
What Are Generics?
Generics allow you to define functions, classes, and interfaces using a placeholder for a type that can be provided later. Instead of designing separate implementations for distinct data types, you can create a single function or class that can handle any type supplied at the time of call. This method encourages code reuse and helps to prevent type mistakes.
Example of Generics
Let’s look at a simple example of a generic function. Suppose you want to create a function that returns the first element of an array, regardless of the type of elements it contains:
function getFirstElement<T>(arr: T[]): T {
return arr[0];
}
const numbers = [1, 2, 3, 4];
const firstNumber = getFirstElement(numbers); // returns 1
const strings = ["apple", "banana", "cherry"];
const firstString = getFirstElement(strings); // returns "apple"
In this example, the function getFirstElement
uses the generic type T
as a placeholder for the type of elements in the array. When you call the function with an array of numbers, TypeScript infers that T
is number
, and when you call it with an array of strings, T
is inferred as string
.
Why Use Generics?
Generics offer various benefits:
- Type Safety: Generics allow you to maintain type safety while writing reusable code. This helps catch type errors at compile time rather than at runtime.
- Code Reusability: Instead of duplicating code for different types, you can create a single implementation that works with any type, leading to cleaner and more maintainable code.
- Flexibility: Generics provide flexibility in how you define and use functions, classes, and interfaces. You can create components that adapt to different data types without sacrificing type safety.
Generics with Interfaces and Classes
Generics can also be applied to interfaces and classes. Here’s an example of a generic interface:
interface Box<T> {
contents: T;
}
const numberBox: Box<number> = { contents: 123 };
const stringBox: Box<string> = { contents: "Hello, TypeScript!" };
In this case, the Box
interface is defined with a generic type T
, allowing you to create boxes that can hold different types of content.
Generic Classes
You can also create generic classes. Here’s an example:
class GenericStack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}
const numberStack = new GenericStack<number>();
numberStack.push(1);
numberStack.push(2);
const lastNumber = numberStack.pop(); // returns 2
const stringStack = new GenericStack<string>();
stringStack.push("TypeScript");
const lastString = stringStack.pop(); // returns "TypeScript"
In this example, the GenericStack
class can handle any type of item, whether it’s a number or a string, while keeping the stack operations type-safe.
Constraints on Generics
Sometimes, you may want to restrict the types that can be used with a generic. You can do this by using constraints. For example, if you want to ensure that a generic type extends a specific interface:
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(item: T): void {
console.log(item.length);
}
logLength("Hello, Generics!"); // works, as strings have a length property
logLength([1, 2, 3]); // works, as arrays have a length property
Here, the function logLength
only accepts types that have a length
property, ensuring type safety.
Conclusion
In conclusion, Generics in TypeScript are an extremely useful feature that improves code reusability, type safety, and flexibility. Generics allow you to define functions, classes, and interfaces using type placeholders, making it easier to write cleaner and more maintainable code. Understanding and using generics can improve your TypeScript projects, regardless of whether you're working with basic functions or complicated data structures.
FAQs
To define a generic function, you use angle brackets (<T>) to specify the type parameter. For example:
typescriptCopy codefunction identity<T>(arg: T): T { return arg; }
Take our Typescript skill challenge to evaluate yourself!
In less than 5 minutes, with our skill challenge, you can identify your knowledge gaps and strengths in a given skill.