Front-End(Web)/Typescript

[Typescript] 유니언과 교차 타입

ttaeng_99 2021. 2. 23. 19:18
반응형

앞서, Enum(열거)과 리터럴 타입을 공부하면서 유니언 타입을 자주 활용하였다.

다양한 타입들을 복합하기 위한 유니언, 그리고 이와 비교되는 교차 타입에 대해서 포스팅하겠다.


💙 Union Type (유니언 타입)

앞서 얘기했듯, 유니언 타입은 새로운 형태의 타입은 아니다. 이미 존재하는 타입들을 재료로 구성하는 방법의 일종이다.

만약, 어떤 변수에 2가지 타입이 기대가 된다.(string, number) 이 땐, any보다 유니언 타입을 쓰는 것이 효과적이다.

let unionPrice: number | string = 5;

이처럼, 우리가 활용하고자 하는 타입들을 파이프(|)로 연결시키기만 하면 된다. 해당 타입들 외 값을 설정하면, 에러가 발생한다.

 

- Union Type 재활용: Type Aliase

만약 위처럼, string | number Union 조합을 여러 곳에서 사용한다고 가정하자. 이를 일일이 타이핑하는 것은 비효율적이다.

이 유니언 타입의 재활용을 위해, Type Aliase를 통해 특정 변수명에 유니언 타입을 저장해준다.

type StrOrNum = number | string;

let unionPrice: StrOrNum;

const calculatePrice(a: number, b: number): StrOrNum {
  // ...
  return a + b;
}

 

- 공통 필드를 갖는 유니언 (Unions with Common Fields)

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

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

declare function getSmallPet(): Fish | Bird;

let pet = getSmallPet();
pet.layEggs();
pet.swim();		// error! Bird의 경우 처리불가

위 같은, 인터페이스 간의 유니언 타입에서 해당될 것 같다. getSmallPet() 함수는, Fish, Bird 두 인터페이스의 유니언 타입이다.

공통요소인 layEggs() 메서드는 처리가 가능하지만, swim() 메서드는 확신할 수 없으므로 오류를 발생한다.

 

- Type Guard

setItemPrice() 함수는 StrOrNum 타입의 인자로 받지만, 이를 number 타입인 itemPrice에 할당하려니 에러가 발생했다.

type StrOrNum = string | number;
let itemPrice: number;

const setItemPrice(price: StrOrNum): void {
  itemPrice = price;
}

 

이를, typeof Operator를 통해 조건부로 처리하면 에러가 사라진다. 이러한 코드검증 과정을 Type Guard(타입가드) 라 칭한다.

const setItemPrice(price: StrOrNum): void {
  if (typeof price === 'string') {
    itemPrice = 0;
  }
  else {
    itemPrice = price;
  }
}

* Javascript의 typeof()는 메서드로 typeof('hello') 와 같이 사용되었다. 문법의 차이를 잘 봐두자!


💙 Intersection Type (교차 타입)

교차 타입은 유니언 타입과 밀접한 관련이 있지만, 사용 방법은 매우 다르다. 교차 타입은 여러 타입을 하나로 결합하는 개념이다.

기존의 타입들을 합쳐, 필요한 모든 기능을 가진 단일 타입을 얻어낼 수 있는 것이다.

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

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

type ArtistsResponse = ArtistsData & ErrorHandling;

const handleArtistsResponse = (response: ArtistsResponse) => {
  if (response.error) {
    console.error(response.error.message);
    return;
  }

  console.log(response.artists);
};

Type Aliase를 통해 ArtistsResponse 라는 타입을 새로 만든다. 이는, 두 인터페이스의 교차타입으로 '&' 로 연결한다.


유니언과 교차타입에 대해 간략하게 정리했으며, and(&), or(|) 느낌과 뭔가 같으면서도 다르다.

유니언의 경우, 인터페이스 간의 공통필드에서는 오히려 and에 가깝게 동작한다. 개별 필드에선 오류가 발생한다.

또한, 교차 타입은 오히려 인터페이스의 모든 필드를 활용가능한 점에서 오히려 or에 가깝다. 이를 혼동하지 말아야겠다.\

 

[출처]

- Typescript 핸드북 : typescript-kr.github.io/pages/basic-types.html#%ED%83%80%EC%9E%85-%EB%8B%A8%EC%96%B8-type-assertions  

- Typescript 가이드북 : yamoo9.gitbook.io/typescript/types/type-assertions  

- kjwsx23 님의 블로그 : kjwsx23.tistory.com/450?category=746259

 

반응형