#3 Use discriminated union instead of optional fields

When defining a set of polymorphic types like Shape, it’s easy to start with:

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

function getArea(shape: Shape) {
  return shape.kind === 'circle' ?
    Math.PI * shape.radius! ** 2
    : shape.width! * shape.height!;
}

The non-null assertions (when accessing radiuswidth, and height fields) are needed because there’s no established relationship between kind and other fields. Instead, discriminated union is a much better solution:

type Circle = { kind: 'circle'; radius: number };
type Rect = { kind: 'rect'; width: number; height: number };
type Shape = Circle | Rect;

function getArea(shape: Shape) {
    return shape.kind === 'circle' ?
        Math.PI * shape.radius ** 2
        : shape.width * shape.height;
}

참고: https://dev.to/zenstack/11-tips-that-help-you-become-a-better-typescript-programmer-4ca1?utm_source=Nomad+Academy&utm_campaign=b10d81b8b2-EMAIL_CAMPAIGN_2023_01_06&utm_medium=email&utm_term=0_4313d957c9-b10d81b8b2-49539437&mc_cid=b10d81b8b2&mc_eid=e598a309bd