Advanced · 18 min
Conditional types
Select types with conditions and recognize union distribution.
Choose a type by its shape
A conditional type checks whether one type is assignable to another. Here "infer" captures an array element type; non-arrays keep their original type. This is a compile-time decision, not a runtime branch.
type ElementOf<T> = T extends readonly (infer Item)[] ? Item : T;
const first: ElementOf<string[]> = "Travel";
const second: ElementOf<number> = 4;
console.log(first + ": " + second);Output
Travel: 4
Control union distribution
A condition on a bare type parameter distributes across union members. Wrapping both sides in tuples tests the union as a whole. Use distribution deliberately when filtering members; use the tuple form for a whole-type decision.
type OnlyText<T> = T extends string ? T : never;
type AllText<T> = [T] extends [string] ? true : false;
const word: OnlyText<string | number> = "Hi";
const all: AllText<string | number> = false;
console.log(word + ": " + all);Output
Hi: false
Put it into practice
- Predict the output and explain which relationships the types enforce.
- Fix the task while preserving its type contract, then check both practice questions.
Try it yourself
Code runs on this device. When you are signed in, drafts sync to your account.
Use the extracted element type
Change "first" to the string "Travel" while keeping the conditional type.
The array branch extracts string, not the array itself or a number.
Show solution
type ElementOf<T> = T extends readonly (infer Item)[] ? Item : T;
const first: ElementOf<string[]> = "Travel";
const second: ElementOf<number> = 4;
console.log(first + ": " + second);The conditional type resolves before execution. A string value satisfies the extracted element type, while the numeric fallback remains valid.