What are Generics in TypeScript?
Learn TypeScript generics: reusable, type-safe functions and classes with type parameters, constraints, defaults, and inference — explained with code and MCQs.
Expected Interview Answer
Generics let you write reusable functions, classes, and types that work over a type parameter supplied later, preserving type information instead of falling back to 'any'.
A generic introduces a placeholder type variable (like <T>) that is filled in when the code is used, so a single definition works for many concrete types while staying type-safe. You can constrain type parameters with 'extends', provide defaults, and infer them from arguments. Generics power built-in types like Array<T>, Promise<T>, and utility types, letting the same logic serve strings, numbers, or custom objects without duplication.
- Reusable, type-safe abstractions over many types
- Preserves the specific type instead of using 'any'
- Constraints enforce required shape via 'extends'
- Better autocomplete and inference at call sites
- Reduces duplicated, near-identical code
AI Mentor Explanation
A generic is like a bat rack designed to hold whatever bat you slot in — a heavy Test bat or a light T20 blade — and it returns exactly that same bat, not a random one. The rack's design never changes, yet it preserves the identity of whatever you place into it, just as <T> preserves the specific type passed in.
Step-by-Step Explanation
Step 1
Introduce a type parameter
Write function identity<T>(value: T): T to declare the placeholder T.
Step 2
Use it in the signature
Reference T for parameters and return type so the type flows through.
Step 3
Let inference fill it in
Calling identity('hi') infers T as string automatically.
Step 4
Add constraints
Use <T extends { length: number }> to require certain properties.
Step 5
Provide defaults
Use <T = string> to supply a fallback type when none is given.
What Interviewer Expects
- Definition of a generic type parameter
- Why generics beat 'any' for type safety
- Use of constraints with 'extends'
- Awareness of type inference at call sites
- Examples like Array<T> or a generic function
Common Mistakes
- Using 'any' and calling it generic
- Over-constraining or under-constraining type parameters
- Forgetting that T is inferred and annotating it needlessly
- Confusing generic constraints with type assertions
Best Answer (HR Friendly)
“Generics are a way to write one flexible piece of code that works with many different data types while staying safe. Instead of writing separate versions for strings, numbers, and objects, you write it once with a placeholder type that gets filled in when the code is actually used.”
Code Example
// Preserves the exact input type
function identity<T>(value: T): T {
return value;
}
const a = identity('hello'); // T inferred as string, a: string
const b = identity(42); // T inferred as number, b: number
// Constraint: T must have a length property
function longest<T extends { length: number }>(x: T, y: T): T {
return x.length >= y.length ? x : y;
}
longest([1, 2, 3], [1, 2]); // ok
longest('abcd', 'ab'); // ok
// longest(3, 5); // Error: number has no 'length'
// Generic class
class Box<T> {
constructor(private value: T) {}
get(): T {
return this.value;
}
}
const box = new Box<string>('packed');
const out: string = box.get();Follow-up Questions
- How do generic constraints with 'extends' work?
- What is a default type parameter?
- How does TypeScript infer generic type arguments?
- What is 'keyof T' and how is it used with generics?
- How do conditional types build on generics?
MCQ Practice
1. What is the main advantage of generics over 'any'?
Generics keep the specific type information and enforce it, whereas 'any' opts out of type checking entirely.
2. What does '<T extends { length: number }>' express?
The 'extends' clause constrains T so only types with a numeric length property are accepted.
3. In 'identity(42)' where 'function identity<T>(v: T): T', what is T?
TypeScript infers the type argument from the value 42, so T is number and the return type is number.
Flash Cards
What is a generic? — A reusable definition parameterised by a type variable filled in when used, preserving type info.
Generic constraint — <T extends U> restricts T to types assignable to U, allowing safe access to U's members.
Default type parameter — <T = string> supplies a fallback type when the caller does not specify one.
Generics vs any — Generics preserve and enforce the specific type; 'any' disables type checking.