Concept Flow - Distributive conditional types
Start with type T
Is T a union?
Final type
Distributive conditional types check each member of a union type separately, then combine the results.
type Example<T> = T extends string ? "yes" : "no"; type Result = Example<string | number>;
| Step | Type T | Condition (T extends string?) | Result for T | Combined Result |
|---|---|---|---|---|
| 1 | string | string extends string? Yes | "yes" | "yes" |
| 2 | number | number extends string? No | "no" | "yes" | "no" |
| 3 | Final | - | - | "yes" | "no" |
| Variable | Start | After 1 | After 2 | Final |
|---|---|---|---|---|
| T | string | number | string | number | - |
| Result for T | - | "yes" | "no" | "yes" | "no" |
Distributive conditional types split union types and apply conditions to each member. Syntax: T extends U ? X : Y If T is a union, condition applies to each member separately. Results combine into a new union type. If T is not a union, condition applies directly. Useful for transforming union types based on conditions.
T extends U ? X : Y when T is a union type?T is a union, TypeScript distributes the condition over each member separately.T is checked against U individually, returning X or Y per member.T extends U ? X : Y syntax in TypeScript.extends ? : syntax [OK]extends ? : pattern in type definitions [OK]type FilterString<T> = T extends string ? T : never;
type Result = FilterString<'a' | 1 | 'b' | true>;
Result?type ExtractNumber<T> = [T] extends [number] ? T : never;
type Result = ExtractNumber<'a' | 1 | 2>;
T in a tuple disables distributive behavior in conditional types.ExtractNumber'a' | 1 | 2 extends number is false, returning never.T into a union of their array types using distributive conditional types?T extends any ? T[] : never applies the array transformation to each union member separately.T extends any ? to distribute over unions [OK]T in tuple disables distributionT[] directly converts whole union, not membersPass the test and this pattern moves unknown