Concept Flow - Why conditional types are needed
Start with generic type
Check condition on type
Return one
Final type
Conditional types check a type condition and choose one type if true, another if false, helping create flexible and precise types.
type IsString<T> = T extends string ? "Yes" : "No"; type A = IsString<string>; type B = IsString<number>;
| Step | Type Parameter T | Condition (T extends string?) | Result Type |
|---|---|---|---|
| 1 | string | true | "Yes" |
| 2 | number | false | "No" |
| Variable | Start | After 1 | After 2 | Final |
|---|---|---|---|---|
| T | generic | string | number | resolved |
| Result Type | unknown | "Yes" | "No" | final |
Conditional types syntax: T extends U ? X : Y They let types choose between X or Y based on whether T fits U. Useful for flexible, precise typing. Example: IsString<T> returns "Yes" if T is string, else "No".
type Result<T> = T extends number ? string : boolean;T extends number ? string : boolean.extends to check type relations: T extends U ? X : Y.type Check<T> = T extends string ? number : boolean; type Result = Check<'hello'>;
T extends string is true.number.type Check<T> = T extends number ? 'num' : 'not num'; type Result = Check<>;
Check requires a type argument, but Check<> is missing it.Flattened?type Flatten<T> = T extends Array ? U : T; type Flattened = Flatten;
number[] | string. Conditional types distribute over unions, so it applies separately to number[] and string.number[], it matches Array<infer U> with U = number, so result is number.string, it does not match array, so result is string.number | string.Pass the test and this pattern moves unknown