Generics
A generic is a type variable — a placeholder like that the caller fills in — letting you write one reusable function, interface, or class that stays fully type-safe for every type it's used with.
Learn Generics in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
A generic is a shipping box that adapts to its contents. The box itself doesn't care whether it holds books or mugs, but once you put books in, the label says "books" and you'll get books back out — not a vague "stuff". Writing is choosing that label at packing time, so everything stays correctly typed end to end instead of being dumped into an untyped any pile.
1. Generic Functions
A generic function declares a type variable in angle brackets — — and uses it in the parameters and return type. The key benefit is the link it preserves: whatever type you pass in is the exact type you get back. Most of the time you won't even write the at the call site, because TypeScript infers it from your argument.
2. Multiple Type Parameters & Inference
A generic can take several independent type variables, written or . A function like keeps both types distinct, and a transform like lets the input and output element types differ. TypeScript infers all of them from the arguments you actually pass.
3. Generic Interfaces, Classes & Constraints
Types themselves can be generic. {'interface Box '} and are parameterised by a type you choose when you use them, so a only accepts numbers. A constraint — {' '} — restricts what T may be so you can safely use specific members of it inside the function.
🎯 Your Turn
Write a generic last that returns the final element of an array (or undefined for an empty one). Fill in the two blanks marked ___ , then run it.
No blanks this time — just a brief and a starting outline. Build the generic helper yourself, run it, and check your output against the example in the comments.
Practice quiz
What is a generic in TypeScript?
- A function that returns any
- A way to disable type checking
- A type variable the caller fills in
- A runtime cast operator
Answer: A type variable the caller fills in. A generic like <T> is a type variable: a placeholder for a type the caller chooses.
What does function identity<T>(value: T): T guarantee?
- The return type matches the type passed in
- It always returns a string
- The argument is converted to any
- The function runs faster
Answer: The return type matches the type passed in. identity<T> links input to output, so whatever type you pass in is the exact type you get back.
Why are generics preferred over any?
- any is a syntax error
- any cannot be used in functions
- Generics run at runtime, any does not
- Generics preserve type safety while any throws it away
Answer: Generics preserve type safety while any throws it away. any switches off type checking; a generic keeps the input-output relationship type-checked.
What is the return type of first<T>(arr: T[]): T | undefined when called as first([10, 20])?
- any
- number | undefined
- number
- T
Answer: number | undefined. The generic remembers the element type, so the result is number | undefined, not any.
Do you usually have to write the type argument explicitly, as in identity<string>("hi")?
- No, TypeScript usually infers it from the argument
- Yes, always
- Only for numbers
- Only inside classes
Answer: No, TypeScript usually infers it from the argument. TypeScript infers the type parameter from your arguments, so identity("hi") infers T = string.
What does a constraint like <T extends { length: number }> do?
- Forces T to be a number
- Removes the length property
- Limits T to types that have a length property
- Makes T optional
Answer: Limits T to types that have a length property. The constraint requires T to have a .length, so reading a.length inside is safe.
How many independent type parameters can a generic declare?
- Exactly one
- Several, like <A, B> or <T, U>
- At most two
- Unlimited but they must be equal
Answer: Several, like <A, B> or <T, U>. A generic can take multiple independent type variables, each its own placeholder.
In mapValues<T, U>(arr: T[], fn: (x: T) => U): U[], what are T and U?
- The same type always
- Both must be strings
- Runtime values, not types
- Input element type and output element type
Answer: Input element type and output element type. T is the input element type and U the output element type; they are independent and inferred.
What is true of generic type parameters at runtime?
- They are enforced with runtime checks
- They are erased; generics are compile-time only
- They become hidden function arguments
- They slow the program down
Answer: They are erased; generics are compile-time only. Type parameters disappear at runtime; generics are a purely compile-time feature.
Which of these is a built-in generic type in TypeScript?
- console.log
- typeof
- Promise<T>
- switch
Answer: Promise<T>. Array<T>, Promise<T>, Map<K, V>, and Record<K, V> are all built-in generics.