type Circle = { kind: 'circle'; radius: number };
type Square = { kind: 'square'; sideLength: number };
type Triangle = { kind: 'triangle'; base: number; height: number };

type Shape = Circle | Square | Triangle;

function calculateArea(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2;
    case 'square':
      return shape.sideLength ** 2;
    case 'triangle':
      return (shape.base * shape.height) / 2;

    default: {
      const _exhaustiveCheck: never = shape;
      throw new Error(
        `Unhandled discrimated union case: ${JSON.stringify(_exhaustiveCheck)}`
      );
    }
  }
}

const circle: Circle = { kind: 'circle', radius: 5 };
const square: Square = { kind: 'square', sideLength: 10 };
const triangle: Triangle = { kind: 'triangle', base: 5, height: 10 };

console.log(calculateArea(circle));
console.log(calculateArea(square));
console.log(calculateArea(triangle));
