Master conditional ternary type logic (T extends U ? X : Y) and type pattern extraction using the infer keyword.
Discover how TypeScript infers types automatically and how let versus const declarations shape wide types versus narrow literal types.
Just as runtime code uses ternary conditionals (condition ? a : b), TypeScript supports Conditional Types in type space:
T extends U ? TrueType : FalseType
type IsString<T> = T extends string ? true : false;
type A = IsString<"hello">; // true
type B = IsString<42>; // false
infer KeywordInside a conditional type's extends clause, the infer keyword declares a type variable that TypeScript will automatically extract and infer:
// Custom utility: Extract array element type
type ElementOf<T> = T extends (infer Element)[] ? Element : T;
type NumberItem = ElementOf<number[]>; // Inferred as: number
type StringItem = ElementOf<string>; // Inferred as: string
// Extract Promise resolved value type
type AwaitedType<T> = T extends Promise<infer Resolved> ? Resolved : T;
type AsyncData = AwaitedType<Promise<{ id: number }>>; // Inferred as: { id: number }
[ Input Type: Promise<string> ] ──> Matches Promise<infer Resolved>
│
▼
[ Extracted Type ] ──> Resolved = string
infer Outside Conditional Extends Clauses: The infer keyword CANNOT be used outside a conditional type's extends clause!Conditional types power modern state libraries and framework types. Next, let me explain Deep Readonly and Recursive Type Aliases!