TypeScript
Pattern matching
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;
}
}
Exercise 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 })).
Show example 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 }));
Test yourself
-
Which construct is most suitable for processing a discriminated union?
- try/catch
- for loop
- while loop
- switch statement
Show answer
switch statement — A switch statement narrows to each member based on the discriminant value; each case corresponds to a member and provides pattern matching.
-
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;
}
}
Show answer
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;
}
}
-
Pattern matching parts
- 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
Next lesson: Summary - Discriminated unions