[TIL] 2022/03/07 Mon - 타입스크립트 유니온 타입과 인터섹션 타입
타입스크립트 유니온 타입(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)은 여러 타입을 모두 만족하는 하나의 타입을 의미한다. & 여산자를 이용해 여러 개의 타입 정의를 하나로 합치는 방식을 인터섹션 타입 정의 방식이라고 한다.
아래의 코드는 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 타입 오류
}