MediumJavaScriptTypeScript

Exhaustive Discriminated Union (never)

TypeScriptTypesPatterns

A discriminated union is a union where every member has a shared literal property (the discriminant). TypeScript uses it to narrow types in a switch:

type Shape =
  | { kind: 'circle';    radius: number }
  | { kind: 'rectangle'; width: number; height: number }

function area(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':    return Math.PI * shape.radius ** 2;
    //                                 ^ TypeScript: shape is Circle ✅
    case 'rectangle': return shape.width * shape.height;
    //                          ^ TypeScript: shape is Rectangle ✅
  }
}

Exhaustiveness checking with never

The never type represents impossible values. If you add a new shape variant and forget to handle it, TypeScript catches it via assertNever:

function assertNever(x: never): never {
  throw new Error('Unhandled: ' + JSON.stringify(x));
}

// In the switch default:
default: return assertNever(shape);
// If Triangle is not handled, shape is still Triangle here → TypeScript error:
// Argument of type 'Triangle' is not assignable to parameter of type 'never'

Implement area(shape: Shape)

ShapeFormula
squareside²
rectanglewidth × height
triangle(base × height) / 2
rhombus(d1 × d2) / 2

Sample tests

Test #1triangle base=6, height=4
Input: ["triangle",6,4]
Output: 12
Test #2triangle base=10, height=5
Input: ["triangle",10,5]
Output: 25
Test #3rhombus d1=6, d2=8
Input: ["rhombus",6,8]
Output: 24
Test #4rectangle 4×4 (same as square)
Input: ["rectangle",4,4]
Output: 16
Test #5square area = side²
Input: ["square",4]
Output: 16
Test #6square 3×3
Input: ["square",3]
Output: 9
Test #7rectangle 3×5
Input: ["rectangle",3,5]
Output: 15