what i learned/TIL

[TIL] 2022/03/07 Mon - 타입스크립트 유니온 타입과 인터섹션 타입

zubetcha 2022. 3. 7. 22:14

 

 

타입스크립트 유니온 타입(Union Type)

 

유니온 타입(Union Type)이란?

유니온 타입(Union Type)이란 자바스크립트의 OR 연산자 (||)와 같이 'A 또는 B이다' 라는 의미의 타입이다. 아래의 코드에서 logText()함수의 파라미터 text에는 문자열 타입이나 숫자 타입이 모두 올 수 있다. 이처럼 | 연산자를 이용하여 여러 개의 타입을 연결하는 방식을 유니온 타입 정의 방식이라고 한다.

 

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

 

유니온 타입의 장점

any 타입 대신 유니온 타입을 사용하면 추론하는 타입이 확정되어 있기 때문에 해당 타입과 관련된 API를 작성할 때 자동 완성되어 오탈자로 인한 에러 발생을 현저히 감소시킬 수 있다. 즉, any를 사용하면 일반 자바스크립트로 작성하는 것처럼 동작하지만, 유니온 타입을 사용하면 타입스크립트의 이점을 살리면서 개발이 가능해진다.

 

// any를 사용하는 경우
function getAge(age: any) {
  age.toFixe(); // 에러 발생, age의 타입이 any로 추론되기 때문에 숫자 관련된 API를 작성할 때 코드가 자동 완성되지 않는다.
  return age;
}

// 유니온 타입을 사용하는 경우
function getAge(age: number | string) {
  if (typeof age === 'number') {
    age.toFixed(); // 정상 동작, age의 타입이 `number`로 추론되기 때문에 숫자 관련된 API를 쉽게 자동완성 할 수 있다.
    return age;
  }
  if (typeof age === 'string') {
    return age;
  }
  return new TypeError('age must be number or string');
}

 

타입스크립트 인터섹션 타입(Intersection Type)

 

인터섹션 타입(Intersection Type)이란?

인터섹션 타입(Intersection Type)여러 타입을 모두 만족하는 하나의 타입을 의미한다. & 여산자를 이용해 여러 개의 타입 정의를 하나로 합치는 방식을 인터섹션 타입 정의 방식이라고 한다.

 

Intersection Type

 

 

아래의 코드는 Person 인터페이스에서 정의한 타입과 Developer 인터페이스에서 정의한 타입을 & 연산자를 이용하여 합친 후 Zubetcha 라는 타입에 할당한 코드이다. 

 

interface Person {
  name: string;
  age: number;
}
interface Developer {
  name: string;
  skill: number;
}
type Zubetcha = Person & Developer;

 

결과적으로 Zubetcha 타입은 아래와 같이 정의된다.

 

{
  name: string;
  age: number;
  skill: string;
}

 

유니온 타입을 사용할 때 주의할 점

아래의 코드에서 introduce() 함수의 파라미터 타입을 Person, Developer 인터페이스의 유니온 타입으로 정의하였다. 유니온 타입을 OR 라고 사고하여 '유니온 타입은 A도 될 수 있고, B도 될 수 있는 타입이지' 라고 생각하고 두 인터페이스가 제공하는 속성들을 모두 사용할 수 있을 것이라고 생각할 수도 있다. 하지만 타입스크립트 관점에서는 introduce() 함수를 호출하는 시점에 Person 타입이 올지, Developer 타입이 올지 알 수 없기 때문에 어느 타입이 들어와도 오류가 나지 않는 방향으로 타입을 추론하게 된다. 따라서 introduce() 함수 안에서는 별도로 타입의 범위를 좁히지 않는 이상 Person 인터페이스와 Developer 인터페이스의 공통되는 속성인 name만 사용할 수 있게 되는 것이다.

 

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 타입 오류
}