Syntax
T extends U ? TrueType : FalseTypeExamples
A Basic Conditional Type
Selecting a type based on whether another type satisfies a condition.
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"
type ExtractArray<T> = T extends (infer U)[] ? U : T;
type C = ExtractArray<number[]>; // number - extracted the element type
type D = ExtractArray<string>; // string - unchanged, T was not an arrayPractical Use: A Custom Utility Type
Building a type that filters out null/undefined, a common real-world pattern.
type NonNullable<T> = T extends null | undefined ? never : T;
type A = NonNullable<string | null>; // string
type B = NonNullable<number | undefined>; // number
// This is actually one of TypeScript's own built-in utility typesBest practices
- Use conditional types when a type needs to adapt its shape based on characteristics of another type, similar to overloaded function behavior at the type level
- Study TypeScript's own built-in utility types (like NonNullable, ReturnType) - many are implemented using conditional types and are excellent learning examples
- Keep conditional types as simple as possible - deeply nested conditional chains become genuinely difficult for anyone (including future you) to read
- Combine conditional types with infer when you need to extract and reuse part of the matched type, not just branch based on 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.The infer Keyword
infer, used only within the extends clause of a conditional type, lets you declare a new type variable that captures part of a matched structure, so it can be reused in the result. It is the mechanism behind utility types like ReturnType<T> and Parameters<T>, which extract specific pieces of a function's type signature.
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.The infer Keyword
infer, used only within the extends clause of a conditional type, lets you declare a new type variable that captures part of a matched structure, so it can be reused in the result. It is the mechanism behind utility types like ReturnType<T> and Parameters<T>, which extract specific pieces of a function's type signature.