Syntax
T extends SomePattern<infer U> ? U : neverExamples
Extracting a Function's Return Type
A simplified version of how TypeScript's built-in ReturnType<T> actually works.
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function getUser() {
return { id: 1, name: "Alice" };
}
type User = MyReturnType<typeof getUser>;
// User is inferred as: { id: number; name: string }Extracting an Array's Element Type
Unwrapping the inner type from an array or Promise.
type ElementType<T> = T extends (infer Item)[] ? Item : never;
type A = ElementType<string[]>; // string
type B = ElementType<number[]>; // number
type UnwrapPromise<T> = T extends Promise<infer Value> ? Value : T;
type C = UnwrapPromise<Promise<string>>; // stringBest practices
- Use infer specifically when you need to extract and reuse a piece of a matched type, rather than just checking whether it matches
- Study infer through TypeScript's built-in utility types (ReturnType, Parameters, Awaited) - they are the clearest real-world examples of this pattern
- Remember infer can only appear within the extends clause of a conditional type - it has no meaning outside that specific context
- Keep infer-based types well-named and documented, since the syntax itself is dense and can be hard to parse at a glance for readers unfamiliar with it
At a glance
- Purpose
- Static types for JavaScript
- File extension
- .ts ยท .tsx
- Runs in
- Compiled to JavaScript
- Usually used with
- JavaScript and its ecosystem
Specifications & further reading
Related TypeScript documentation
Generics Basics
Generics let you write reusable functions, classes, and types that work with a variety of types while still preserving type safety - rather than using any and losing that safety, or writing near-duplicate code for each type. A generic type parameter, conventionally named T, acts as a placeholder that gets filled in with a real type each time it is used.Generic Constraints
By default, a generic type parameter can be anything. The extends keyword constrains it to only types compatible with a given shape, letting you safely access specific properties or methods within the generic function while still supporting many different concrete types.Generic Classes and Interfaces
Classes and interfaces can also be generic, letting you build reusable data structures (like a Stack, Queue, or API response wrapper) that work with any type while remaining fully type-safe for whichever specific type is used in each instance.Conditional Types
A conditional type selects between two types based on a condition, using syntax that mirrors JavaScript's ternary operator: T extends U ? X : Y. This lets you build types that adapt based on the shape of another type, forming the foundation for many of TypeScript's built-in utility types.
Generics let you write reusable functions, classes, and types that work with a variety of types while still preserving type safety - rather than using any and losing that safety, or writing near-duplicate code for each type. A generic type parameter, conventionally named T, acts as a placeholder that gets filled in with a real type each time it is used.Generic Constraints
By default, a generic type parameter can be anything. The extends keyword constrains it to only types compatible with a given shape, letting you safely access specific properties or methods within the generic function while still supporting many different concrete types.Generic Classes and Interfaces
Classes and interfaces can also be generic, letting you build reusable data structures (like a Stack, Queue, or API response wrapper) that work with any type while remaining fully type-safe for whichever specific type is used in each instance.Conditional Types
A conditional type selects between two types based on a condition, using syntax that mirrors JavaScript's ternary operator: T extends U ? X : Y. This lets you build types that adapt based on the shape of another type, forming the foundation for many of TypeScript's built-in utility types.