Union Type / Intersection Type

Gom·2021년 7월 17일
0

TypeScript

목록 보기
1/5

Union Type

  • 의미 : 여러 타입 중 하나가 될 수 있는 값
  • 필요한 상황 : 두 개 이상의 타입을 가질 수 있는 변수를 만들고자할 때 any를 사용하는 것은 변수에 타입을 지정하여 예측 가능성을 높이기 위한 타입스크립트의 목적과 일치하지 않으므로 유니언 타입을 이용해 타입을 지정해야 한다.
  • 표현 : | 로 각 타입을 구분
//case 1 

function (parameter: string | number | boolean) {
// 값의 타입이 number, string, boolean이 될 수 있음을 의미한다.
}

🔎 Union Type을 사용하는 기술

Unions with Common Fields

  • 의미 : 유니언 타입인 값이 있으면 유니언에 있는 모든 타입에 공통인 멤버들에만 접근할 수 있다.
  • 필요한 상황 : A|B 타입을 가지는 경우 확신할 수 있는 것은 A와 B 둘의 공통 멤버를 가지고 있다는 것 뿐이다. 아래 사례처럼 Fish 타입에만 존재하는 swim 메소드를 이용할 경우 실제 입력된 변수가 Bird인 경우 런타임에서 오류가 발생할 수 있으므로 공통 멤버를 사용해야 한다.

//case 2

interface Bird {
	fly(): void;
    layEggs(): void;
}

interface Fish {
	swim(): void;
    layEggs(): void;
}

declare function getSmallPet(): Fish | Bird;

let pet = getSmallPet();
pet.layEggs(); // 두 타입에 공통으로 존재

pet.swim(); // 두 타입 중 하나에서만 사용 가능

Discriminating Unions

유니언을 사용할 때 TypeScript가 현재 가능한 타입 추론의 범위를 좁혀나가게 해줄 수 있는 리터럴 타입을 갖는 단일 필드를 사용하는 것이 일반적이다.

공통 필드인 state가 아닌 다른 프로퍼티에 접근하는 것은 오류를 발생시키기 때문이다.
아래 사례에서 state가 그 역할을 한다. switch문을 이용해 state값에 따른 분기 처리를 한다.

type NetworkLoadingState = {
  state: "loading";
};

type NetworkFailedState = {
  state: "failed";
  code: number;
};

type NetworkSuccessState = {
  state: "success";
  response: {
    title: string;
    duration: number;
    summary: string;
  };
};

type NetworkState =
  | NetworkLoadingState
  | NetworkFailedState
  | NetworkSuccessState;

function networkStatus(state: NetworkState): string {
  // 현재 TypeScript는 셋 중 어떤 것이
  // state가 될 수 있는 잠재적인 타입인지 알 수 없다.

  // 모든 타입에 공유되지 않는 프로퍼티에 접근하려는 시도는
  // 오류를 발생시킨다.
  state.code;

  // state에 swtich문을 사용하여, TypeScript는 코드 흐름을 분석하면서
  // 유니언 타입을 좁혀나갈 수 있다.
  switch (state.state) {
    case "loading":
      return "Downloading...";
    case "failed":
      // 여기서 타입은 NetworkFailedState일 것이며,
      // 따라서 `code` 필드에 접근할 수 있습니다.
      return `Error ${state.code} downloading`;
    case "success":
      return `Downloaded ${state.response.title} - ${state.response.summary}`;
  }
}

Intersection Types

  • 의미 : 교차 타입은 여러 타입을 하나로 결합한다. 기존 타입을 합쳐 필요한 기능을 모두 가진 단일 타입을 얻을 수 있다.
  • 필요한 상황 : 재사용성이 높은 공통 필드를 가진 기능을 분리하여 여러 타입과 결합하여 사용할 수 있다. 아래 예시에서는 일관된 에러를 다루는 여러 네트워크 요청이 있을 때 에러 핸들링을 분리하여 하나의 응답 타입에 대응하는 결합된 자체 타입을 만들었다.
  • 표현 : &로 각 타입을 결합

interface ErrorHandling {
  success: boolean;
  error?: { message: string };
}

interface ArtworksData {
  artworks: { title: string }[];
}

interface ArtistsData {
  artists: { name: string }[];
}

// 이 인터페이스들은
// 하나의 에러 핸들링과 자체 데이터로 구성된다.

type ArtworksResponse = ArtworksData & ErrorHandling;
type ArtistsResponse = ArtistsData & ErrorHandling;

출처 : https://typescript-kr.github.io/pages/enums.html

profile
안 되는 이유보다 가능한 방법을 찾을래요

0개의 댓글