TypeScript Conditional Types
A conditional type is a type-level if that picks a result type by checking one type against another. Its written form places the check first and then names two branch types.
A conditional type checks a type
IsText checks its input against string. One input takes the true branch and the other takes the false branch.
type IsText<T> = T extends string ? 'yes' : 'no';
type A = IsText<string>;
type B = IsText<number>;
const a: A = 'yes';
const b: B = 'no';
console.log(a);
console.log(b);A conditional picks a label per input
Describe chains two checks to pick one label per input type. Each alias below names the label for one input.
type Describe<T> = T extends string ? 'text value' : T extends number ? 'number value' : 'other value';
type D1 = Describe<string>;
type D2 = Describe<number>;
type D3 = Describe<boolean>;
const d1: D1 = 'text value';
const d2: D2 = 'number value';
const d3: D3 = 'other value';
console.log(d1);
console.log(d2);
console.log(d3);A value outside the result is refused
LabelFor gives number inputs the code label. The text label sits outside that result, so the assignment fails.
type LabelFor<T> = T extends string ? 'text' : 'code';
type CodeLabel = LabelFor<number>;
const label: CodeLabel = 'text';
console.log(label);Example
type Reply<T> = T extends string ? { text: string } : T extends number ? { code: number } : { flag: boolean };
type TextReply = Reply<string>;
type CodeReply = Reply<number>;
const a: TextReply = { text: 'ok' };
const b: CodeReply = { code: 200 };
console.log(a.text);
console.log(b.code);Key points
- The written form is T extends U ? X : Y, with X for a match and Y for a miss.
- The word extends in a type check asks whether values of the first type fit the second type.
- A conditional type can check its own result again, so chained conditionals act like else-if branches.
- The result of a conditional type is an ordinary type that variables and parameters can use.
- A value outside the computed result is refused like any other wrong value.
In this example, Reply builds an object shape per input, so a text reply carries a text field and a code reply carries a numeric code field.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท TypeScript Playground
Exercise
What does the conditional type T extends string ? 'text' : 'code' produce for T set to number?