Pattern matching
- TypeScript course
- Advanced
- Lesson 31/57
- 4 min
Learn branching with discriminated unions.
Pattern matching
Discriminated unions are processed with a switch statement; each case narrows to a member based on the discriminant value. This approach is called pattern matching. When all members are covered, TypeScript warns if a case is missing.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle":
return Math.PI * s.radius ** 2;
case "square":
return s.size ** 2;
}
}Exhaustiveness check
In a switch statement, if all members are covered by cases, TypeScript warns when a case is missing. Writing all cases instead of adding a default branch is safer; when a new member is added, the compiler shows where a case is missing.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.size ** 2;
}
}Practice Shape area with switch
Define the Shape discriminated union type: "circle" (radius: number), "square" (size: number), "rectangle" (width: number, height: number) members, with a kind discriminant field. Write an area(s: Shape): number function using switch (s.kind). For circle return Math.PI * s.radius ** 2, for square return s.size ** 2, for rectangle return s.width * s.height. Print the result via console.log(area({ kind: "rectangle", width: 4, height: 5 })).
Starter code
// Shape discriminated union türünü tanımla (kind discriminant, circle, square, rectangle üyeleri)
// area fonksiyonunu discriminant kontrolüyle switch ile yaz
// rectangle şeklinin alan sonucunu yazdırSample solution
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number }
| { kind: "rectangle"; width: number; height: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle":
return Math.PI * s.radius ** 2;
case "square":
return s.size ** 2;
case "rectangle":
return s.width * s.height;
}
}
console.log(area({ kind: "rectangle", width: 4, height: 5 }));Expected output
20
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Which construct is most suitable for processing a discriminated union?
- try/catch
- for loop
- while loop
- switch statement Correct answer
Explanation: A switch statement narrows to each member based on the discriminant value; each case corresponds to a member and provides pattern matching.
2 switch case narrowing
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(s: Shape): number {
switch (s.kind) {
case ____:
return Math.PI * s.radius ** 2;
case "square":
return s.size ** 2;
}
}
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle":
return Math.PI * s.radius ** 2;
case "square":
return s.size ** 2;
}
}
Explanation: The switch case "circle" narrows the Shape union to the circle member; inside the case body s.radius is safe to use.
3 Pattern matching parts
| Term | Meaning |
|---|---|
switch ifadesi |
branch by discriminant |
case "circle" |
narrows to circle member |
Exhaustiveness check |
warns about missing case |
default branch |
used when not all members covered |