What is the infer Keyword in TypeScript?
Learn how the TypeScript infer keyword captures types inside conditional types, powering utilities like ReturnType and Awaited, with clear code examples.
Expected Interview Answer
The infer keyword declares a type variable inside a conditional type's extends clause, letting TypeScript capture and reuse a piece of another type that is only known during type checking.
It can only appear in the extends condition of a conditional type. When the compiler matches the checked type against the pattern, it binds the inferred position to a fresh type variable that you can reference in the true branch. This powers utilities like ReturnType, Parameters, and Awaited, which pull the return type, argument tuple, or resolved value out of a function or promise type without you writing it out manually.
- Extracts nested types without manual annotation
- Powers built-in utilities like ReturnType and Parameters
- Enables generic, reusable type transformations
- Keeps derived types in sync with their source automatically
- Avoids duplicating type information across a codebase
AI Mentor Explanation
Think of a match-summary tool that watches a full innings and must report the top scorer without being told who it is. It scans every partnership, and the moment it finds the highest score it binds that batter into a slot it can name later. infer works the same way: it inspects a type, latches onto the piece you point at, and hands you a named slot you can reuse in the result.
Step-by-Step Explanation
Step 1
Start with a conditional type
Write T extends Pattern ? X : Y, since infer is only legal inside the extends clause of a conditional type.
Step 2
Place infer in the pattern
Mark the position whose type you want captured, e.g. (...args: any[]) => infer R to grab a function's return type.
Step 3
Bind the type variable
The compiler matches the checked type against the pattern and binds R to whatever occupied that slot.
Step 4
Use it in the true branch
Reference the captured variable (R) in the conditional's true branch to return or transform the extracted type.
Step 5
Handle the false branch
Provide a fallback like never or unknown for when the type does not match the pattern.
What Interviewer Expects
- That infer only works inside a conditional type's extends clause
- Ability to write ReturnType or Parameters from scratch using infer
- Understanding that infer captures a type the compiler determines during matching
- Awareness of multiple infer positions and how unions can result
- A clear, correct code example
Common Mistakes
- Trying to use infer outside a conditional type's extends clause
- Referencing the inferred variable in the false branch where it is out of scope
- Confusing infer with a generic type parameter declared on the alias
- Forgetting that multiple matches can widen the inferred type to a union
- Assuming infer works at runtime rather than only during type checking
Best Answer (HR Friendly)
“The infer keyword lets TypeScript automatically pull a piece of type information out of a bigger type instead of you writing it by hand. It is how built-in helpers figure out things like what a function returns, keeping your types accurate and in sync.”
Code Example
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never
function getUser() {
return { id: 1, name: 'Ada' }
}
type User = MyReturnType<typeof getUser>
// User = { id: number; name: string }
// Unwrapping a Promise
type Unwrap<T> = T extends Promise<infer V> ? V : T
type A = Unwrap<Promise<string>> // string
type B = Unwrap<number> // numberFollow-up Questions
- How would you implement the built-in Parameters<T> utility using infer?
- What happens when infer appears in multiple positions of the same pattern?
- How does infer behave with covariant versus contravariant positions?
- Why can't you reference an inferred variable in the false branch?
- How does distributive conditional typing interact with infer over a union?
MCQ Practice
1. Where is the infer keyword allowed to appear?
infer is only valid in the extends condition of a conditional type, where it captures a matched type into a variable.
2. What does T extends Promise<infer V> ? V : T return when T is Promise<number>?
The type matches Promise<infer V>, binding V to number, so the true branch returns number.
3. Which built-in utility is most directly implemented with infer?
ReturnType uses T extends (...args: any[]) => infer R ? R : any to capture the return type.
Flash Cards
What does infer do? — Captures a type from a matched pattern inside a conditional type's extends clause and binds it to a reusable variable.
Where can infer be used? — Only within the extends clause of a conditional type — nowhere else.
Write ReturnType with infer — type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any
Can you use the inferred variable in the false branch? — No — it is only in scope in the true branch of the conditional type.