Generics allow a class to work with different types while maintaining full type safety. Without generics, a Stack would accept and return any:
// Without generics — loses type information:
class Stack {
push(item: any): void { ... }
pop(): any { ... } // caller doesn't know what they get back
}
// With generics — full type safety:
class Stack<T> {
push(item: T): void { ... }
pop(): T | undefined { ... } // TypeScript knows the exact type
}
const stack = new Stack<number>();
stack.push(42); // ✅
stack.push('hello'); // ❌ TypeScript error
const top = stack.pop(); // TypeScript: number | undefined ✅Stack<T>| Method | Return type | Behavior | |
|---|---|---|---|
push(item) | number | Adds item, returns new size | |
pop() | `T \ | undefined` | Removes and returns top |
peek() | `T \ | undefined` | Returns top without removing |
size() | number | Current item count | |
isEmpty() | boolean | True when size is 0 | |
toArray() | T[] | Copy: bottom to top |
Sample tests