5 min read
TypeScript Generics: The Ultimate Guide, 2025


Hi guys,
in this article we will look at Typescript Generics, what they are and how to use them. Oops!
in this article we will look at Typescript Generics, what they are and how to use them. Oops!
Generics in TypeScript are a powerful tool for writing reusable,
type-safe code. Whether you're a beginner or an experienced developer,
mastering generics will level up your TypeScript skills.
In this complete guide, you'll learn:
- What generics are and why they matter
- How to use generics in functions, interfaces, and classes
- Real-world examples with best practices
- Advanced patterns (conditional types, mapped types, and more)
By the end, you'll confidently use generics like a TypeScript pro.
Fasten your seatbelts, let's dive in!
1. What Are Generics in TypeScript?
Generics allow you to write flexible and reusable components
without sacrificing type safety. Instead of using
any
, generics let you preserve
types while working with different data structures.Why Use Generics?
- Avoid code duplication – Write one function that works with multiple types.
- Better type inference – Get autocompletion and error checking.
- Safer than
any
– Maintain strict typing without runtime errors.
Basic Generic Example
function identity<T>(arg: T): T {
return arg;
}
// Usage
const output = identity("Hello Generics from ITsoftMake.COM!"); // Type: string
const numOutput = identity(42); // Type: number
Here,
<T>
is a type variable that captures the input type.
2. Using Generics in Functions
Generic Functions
function logAndReturn<T>(value: T): T {
console.log(value);
return value;
}
const result = logAndReturn(23); // Logs: 23
Multiple Type Parameters
function merge<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
const merged = merge({ name: "Andre" }, { age: 30 }); // { name: "Alice", age: 30 }
3. Generics in Interfaces and Classes
Generic Interfaces
interface ApiResponse<T> {
data: T;
status: number;
}
const userResponse: ApiResponse<{ name: string }> = {
data: { name: "Ritesh" },
status: 200,
};
Generic Classes
class DataStorage<T> {
private data: T[] = [];
addItem(item: T) {
this.data.push(item);
}
getItems(): T[] {
return this.data;
}
}
const stringStorage = new DataStorage<string>();
stringStorage.addItem("TypeScript Generics - Hi from ITsoftMake.COM");
4. Advanced Generic Patterns
Default Generic Types
function fetchData<T = string>(url: string): Promise<T> {
return fetch(url).then(res => res.json());
}
Constraints with extends
interface HasId {
id: number;
}
function getById<T extends HasId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
Conditional Types
type CheckNumber<T> = T extends number ? "Yes" : "No";
type A = CheckNumber<42>; // "Yes"
type B = CheckNumber<"TS">; // "No"
5. Real-World Use Cases
API Wrappers (Fetch with Type Safety)
async function fetchUser<T>(userId: string): Promise<T> {
const response = await fetch(`/api/users/${userId}`);
return response.json();
}
const user = await fetchUser<{ name: string }>("123");
Utility Functions (e.g. map, filter)
function mapArray<T, U>(arr: T[], mapper: (item: T) =>U): U[] {
return arr.map(mapper);
}
const numbers = [1, 2, 3];
const doubled = mapArray(numbers, x=> x * 2); // [2, 4, 6]
6. Common Mistakes & Best Practices
NO | Overusing any type instead of generics → Loses type safty. |
YES | Use constraints (extends) when needed → Ensures correct types. |
NO | Complex nested generics → Hard to read. |
YES | Keep generics simple and well-documented. Yeees!!! |
Conclusion
Generics make TypeScript scalable and maintainable. By using them effectively, you can:
- Write reusable functions and classes
- Improve type safety over
any
- Handle complex data structures elegantly
Next Step: Try implementing generics in your projects!
And read Official TypeScript Generics Docs!