(참고: www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions)

type NetworkLoadingState = {};

type NetworkFailedState = {
  code: number;
};

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

type NetworkState =
  | NetworkLoadingState
  | NetworkFailedState
  | NetworkSuccessState;

이렇게 NetworkState라는 유니온 타입이 있다고 해보겠습니다. Network 상태가 로딩, 실패, 성공 이렇게 셋 중 하나가 될 수 있으니까 저런식으로 만들었습니다.

이때 NetworkState를 출력하는 함수를 만들고 싶은데, 로딩, 실패, 성공 상태마다 다르게 출력하려면 어떻게 해야 할까요?

 

function printState(state: NetworkState) {
  if ('response' in state) {
    console.log(`Success: ${state.response.title}`);
  } else if ('code' in state) {
    console.log(`Failed: ${state.code}`);
  } else {
    console.log('Loading!');
  }
}

공통 필드가 없기 때문에 이런식으로 property를 검사해야 합니다

좀.. 직관적이지 않습니다

 

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 printState(state: NetworkState) {
  switch (state.state) {
    case 'success':
      console.log(`Success: ${state.response.title}`);
      break;

    case 'failed':
      console.log(`Failed: ${state.code}`);
      break;

    default:
      console.log('Loading!');
  }
}

 

그래서 나온 아이디어는 공통 필드를 하나 부여해주는 겁니다. 이렇게 하면 state 필드를 갖고 어떤 type인지 체크할 수 있습니다

반응형