Concept Flow - Discriminated union narrowing
Start with union type variable
Check discriminant property
Match case A
Use properties
End
We check a special property (discriminant) to know which type we have, then safely use its specific properties.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(shape: Shape) {
if (shape.kind === "circle") {
return Math.PI * shape.radius ** 2;
} else {
return shape.size ** 2;
}
}| Step | Condition | Condition Result | Narrowed Type | Action | Output |
|---|---|---|---|---|---|
| 1 | shape.kind === "circle" | true | { kind: "circle"; radius: number } | Calculate circle area | 28.274333882308138 |
| 2 | shape.kind === "circle" | false | { kind: "square"; size: number } | Calculate square area | 16 |
| 3 | No more cases | - | - | Return result | - |
| Variable | Start | After Step 1 | After Step 2 | Final |
|---|---|---|---|---|
| shape | { kind: "circle", radius: 3 } | { kind: "circle", radius: 3 } | - | - |
| shape | { kind: "square", size: 4 } | - | { kind: "square", size: 4 } | - |
| output | - | 28.274333882308138 | 16 | - |
Discriminated union narrowing: - Use a common 'discriminant' property (like 'kind') - Check this property in conditions - TypeScript narrows type inside each branch - Access only properties valid for that narrowed type - Ensures safe, clear code for union types