[ TypeScript ] union vs intersection

youngjewoo·2021년 10월 4일
2

TS

목록 보기
1/1
post-thumbnail

1. 포스팅 동기


얼마 전 K사의 프론트엔드 면접을 봤는데요!

그 중에 받았던 질문이었습니다.

Q) Intersection과 Union의 차이점이 무엇인가요?

시원하게 대답했다면 좋았겠지만... 아쉽게도 그러지 못했습니다 ㅠ


간단한 내용이지만 따로 정리해주면 분명 더 기억에 남고,

나중에 누가 질문했을 때에도 저만의 언어로 다시 설명이 가능하니까

이 주제에 대해서 포스팅 하게 됐어요!

2. union


첫 번째로 typescript에서의 union이란 다음의 의미와 같습니다.

유니언 타입은 여러 타입 중 하나가 될 수 있는 값을 의미합니다.

정의는 언제나 추상적이죠..? ㅠ


그래서 실제 사용 예시를 한 번 보겠습니다.

type width = number | string;

코드로 보니까 훨씬 간결하네요!

아마 코딩을 해보셨던 분이시라면 ' | ' 의 의미를 이미 알고계시기 때문에

더 빨리 와닿으실 거 같습니다!


결국 union의 의미는

' | '로 연결된 모든 타입이 가능하다

라는 의미로 해석하시면 되겠습니다.


위와 같이 width에 10,20 등 숫자값을 저장할 수도 있겠지만,

10px, 20px 같이 string 값의 저장을 필요로 할 수도 있겠죠?


이처럼 union 두 가지 타입중 어느 것도 될 수 있고,

자바스트립트에서 기본적으로 제공하는 premetive 타입이 아니더라도

사용자가 정의한 객체나 타입에도 적용이 가능합니다.


따라서 기존 타입을 활용해서 새로운 타입을 정의하거나,

하나의 타입에 여러 개가 올 수 있는 경우 유용하게 사용할 수 있는

문법이 되겠습니다!


3. intersection


다음은 intersection 입니다!

제가 차이점을 제대로 설명하지 못한 이유이기도 한데요..


먼저 정의에 대해 말씀드리면,

기존 타입을 합쳐 필요한 기능을 모두 가진 단일 타입으로 만듭니다.

음..? 역시 아리송하군요


실제 코드 예시로 보겠습니다.

interface Coffee {
  beans: string;
}

interface Milk {
  name: string;
  farm: string;
}

type Latte = Coffee & Milk;

위와 같이 코드를 짠다면 결과가 어떻게 나올까요?


결과는 바로!

interface Cafe {
  beans: string; // from Coffe
  name: string;  // from Milk
  farm: string;  // from Milk
}

이런식으로, 두 개의 객체가 가진 프로퍼티가 합쳐진 형태로 나옵니다!

그렇다면 만약!

Q) 이름이 같은 프로퍼티가 있다면 어떻게 될까요?

interface Coffee {
  name: string; // 이름이 똑같은 프로퍼티!
  beans: string;
}

interface Milk {
  name: string; // 이름이 똑같은 프로퍼티!
  farm: string;
}

type Latte = Coffee & Milk;

똑같이 name이라는 프로퍼티를 갖고 있다면?

interface Latte {
  beans: string;
  name: string;
  farm: string;
}

결과는 이름이 같을 경우 하나의 프로퍼티만 남게됩니다!


면접관분께서는 이런 특성 때문에 intersection을 자주 사용한다고 말씀하셨었어요.


저희 프로젝트에서는 이런 경우 주로 상속을 통해 해결했기때문에 사용할 일이 없었지만,

굳이 상속을 사용하지 않더라도 위와 같이 해결할 수 있겠네요!



흐음... 그러면 저는 한 가지 더 찝찝함이 남네요.

만약 이름은 같은데 타입이 다르다면 어떻게 될까요?

// 테스트
interface A { name: string; }
interface B { name: number; }

const a: A & B = { name: ??};

// 결과
interface C { name: never; }

여기까지 읽으시느라 힘들었을테니 한 화면에 테스트 결과를 모두 담아봤습니다.

제가 테스트했을 경우에는 never 타입으로 처리가 됐네요.

다행이도 결국 사용할 수 없는 프로퍼티가 됐습니다.


혹시나 위와 같은 실수를 범하더라도,

에디터에 설정을 잘해놨다면 정적 분석 단계에서 금방 발견할 수 있겠어요!


다만 위 결과는 제 개발환경에서 테스트한 것이라 차이가 있을 수 있습니다!


오늘은 이렇게 union과 intersection에 대해 알아봤구요!

다음 면접에서는 꼭..! 잘 대답할 수 있기를 바라며 이만 마치겠습니다.

하단에 이 글을 쓰며 참고한 링크 첨부합니다.

참고 링크

해당 내용은 타입스크립트 핸드북(union과 intersection) 를 참고했습니다!

profile
Front-end Developer

0개의 댓글