[TS] union (|) 과 intersection (&)

김채운·2023년 2월 14일
0

Typescript

목록 보기
3/7

➡️ union type

A또는 B이다의 의미를 가지고 있는 타입으로 or('또는')의 의미를 가지고 있고 |파이프기호를 사용하며 정확하게는 union이라고 불린다.
💡 (영단어 union 자체가 ‘합집합’이라는 뜻이다.)

function logText(text: string | number) {
  // ...
}

이렇게 매개변수로 들어올 변수들의 타입을 | 연산자를 통해서 열거 형식으로 정의 해줄 수 있다.
그럼 매개변수가 문자열이어도 괜찮고 숫자열이어도 괜찮다는 뜻이 된다.

union을 사용하면 좋은 점은, 매개변수를 폭 넓게 사용할 수 있다는 거다. 하지만 그만큼 타입추론이 정확하게 이루어지지 않는다는 단점이 있다.

❗union type 사용시 주의할 점.

interface Person {
  name: string;
  age: number;
}
interface Developer {
  name: string;
  skill: string;
}
function introduce(someone: Person | Developer) {
  someone.name; // O 정상 동작
  someone.age; // X 타입 오류
  someone.skill; // X 타입 오류
}

interface Person과 interface Developer를 union을 사용해서 introduce 함수의 매개변수 someone의 타입으로 정의했다. 여기서의 문제점이 뭐냐면,
Person과 Developer에 공통으로 들어있는 name이라는 속성에는 접근이 가능하지만, Person에만 있는 age나 Developer에만 있는 skill에 접근하려고 하면 error가 난다는 점이다.
이유는 지금 someone의 타입은 Person 또는 Developer다 하지만 age는 Person에만 있다 타입스크립트는 모든 가능성을 다 고려하기 때문에 Developer에도 있는지를 고려하게 된다. 그리고 Developer에는 age가 없다.
introduce 함수가 실행될 때에는 someone으로 Person이 올 지 Developer가 올 지 모르기 때문에 error가 나는 것이다. Person이면 에러가 나지 않지만 union이기 때문에 Developer 타입일 경우도 고려를 하게 되는 것이다.

이러한 union의 단점이 될 수도 있는 특성은 '타입가드'를 통해 타입을 좁혀서 제대로 타입을 인식할 수 있게 해줄 수 있다.

➡️ intersection type

intersection type은 & 연산자를 사용하고, and('그리고')라고 생각하면 된다. union이 또는 이어서 둘 중에 하나를 충족하면 됐다면, intersection은 여러 타입을 충족해야 된다는 뜻이다.

type A = string & number

지금 이 A 타입은 string이면서 number를 충족해야 된다고 되어있다. 하지만 문자타입이면서 숫자타입을 충족할 만한 게 있나? 정답은 '없다' 저 방식 대신에 객체를 이용하는 방식이 있다.

type A = {hello:'world'} & {chae:'woon'} // 타입을 이렇게 정의하고
const a: A = {hello:'world',chae:'woon'} // 타입에 만족하게 대입을 해본다.

여기서 만약에

const a: A = {hello:'world'} // 이렇게 되면 error가 뜬다. 둘 다 충족하는 게 아니라 하나만 충족하기 때문에

아까 union에서는 접근할 수 없었던 age와 skill이 &을 사용하면 모두 접근이 가능하게 된다.

interface Person {
  name: string;
  age: number;
}
interface Developer {
  name: string;
  skill: string;
}
function introduce(someone: Person & Developer) {
  someone.name; // O 정상 동작
  someone.age; // O 정상 동작
  someone.skill; // O 정상 동작
}

introduce({name:'woon',age:13}) // 이러면 error intersection은 모든 타입을 충족시켜야함
introduce({name:'woon',age:13,skill:'typescript'}) // 이렇게 Developer와 Person 타입의 속성을 모두 전달해줘야 error가 안 남.

이처럼 & 연산자를 이용해 여러 개의 타입 정의를 하나로 합치는 방식을 인터섹션 타입 정의 방식이라고 한다.

보다시피 intersection 방식은 union 방식보다 융통성이 떨어지기 때문에 보통은 intersection type보다는 union type을 자주 사용한다.

출처

0개의 댓글