Generics are a language-independent concept (they also exist in C++, Java, and many other programming languages). They allow you to write flexible yet type-safe code that can handle different data types without sacrificing compile-time checks.
Let’s understand them step by step.
1. The Problem
Suppose you need a function that returns the first element of an array. The array can contain either strings or numbers.
A simple solution could be:
function getFirstElement(arr: (string | number)[]) {
return arr[0];
}
const el = getFirstElement([1, 2, 3]);
This works — but there are problems.
Problem 1: Mixed types allowed
Since we used a union type (string | number)[]
, users can mix types in the same array without TypeScript raising an error:
const el = getFirstElement([1, 2, "3"]); // No error
This is not ideal if we want type consistency.
Problem 2: Return type inference fails
If we call the function with only strings:
const el = getFirstElement(["harkiratSingh", "ramanSingh"]);
console.log(el.toLowerCase());
We expect el
to be a string. However, TypeScript infers the return type as string | number
, forcing us to add extra type checks.
2. The Solution – Generics
Generics let us parameterize types, meaning we can write functions, classes, and interfaces that work with any type while maintaining type safety.
A simple example:
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString");
let output2 = identity<number>(100);
Here, T
is a type variable that represents the type provided at the time of function call.
3. Fixing the Original Problem with Generics
We can rewrite our function using generics:
function getFirstElement<T>(arr: T[]): T {
return arr[0];
}
Now:
const el = getFirstElement(["harkiratSingh", "ramanSingh"]);
console.log(el.toLowerCase()); // ✅ Works fine
TypeScript correctly infers that el
is a string
.
Issue Resolved
- Type Safety: If you try to mix different types in the array, TypeScript warns you:
const el = getFirstElement<string>(["harkiratSingh", 2]);
// ❌ Error: Type 'number' is not assignable to type 'string'
- Correct Return Type: TypeScript now knows the exact type of the return value, so we can safely call string methods on it.
4. Key Takeaways
- Without generics, TypeScript struggles to enforce consistency in scenarios where multiple types are possible.
- Generics allow you to write reusable, flexible, and type-safe functions.
- The
<T>
acts like a placeholder that gets replaced with the actual type during function calls.
✅ In summary: Generics make your code more powerful and safer by combining flexibility with strict type checks. They are a must-know feature when writing scalable TypeScript applications.
Top comments (0)