교차 타입은 여러 타입을 하나로 결합합니다. 기존 타입을 합쳐 필요한 모든 기능을 가진 하나의 타입을 얻을 수 있습니다. 예를 들어 Person & Serializable & Loggable 이러한 타입은 세가지 타입의 모든 멤버를 갖게 됩니다.

유니언 타입

유니언 타입은 값이 여러 타입 중 하나임을 설명합니다. | 로 각 타입을 구분하여 number | string | boolean 은 값이 number, string 혹은 boolean 이 될 수 있음을 나타냅니다.

유니언 타입을 값으로 가지고 있으면, 기본적으로는 유니언에 있는 모든 타입의 공통인 멤버에만 접근할 수 있습니다.

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

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

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
pet.layEggs(); // 성공
pet.swim();    // 오류

타입 가드와 차별 타입 (Type Guards and Differentiating Types)

유니온 타입을 구분하는 방법은 무엇이 있을까요? 간단하게는 프로퍼티가 있는지 확인하고 타입 assertion을 사용할 수 있습니다.

let pet = getSmallPet();

if ((pet as Fish).swim) {
    (pet as Fish).swim();
} else if ((pet as Bird).fly) {
    (pet as Bird).fly();
}

사용자-정의 타입 가드 (User-Defined Type Guards)

위 코드는 그렇게 나이스해 보이지 않습니다. 마침 Typescript에는 타입 가드라는 것이 있습니다.

타입 서술어 사용하기 (Using type predicates)

타입 가드를 정의하기 위해, 반환 타입이 타입 서술어인 함수를 정의만 하면 됩니다.

function isFish(pet: Fish | Bird): pet is Fish {
    return (pet as Fish).swim !== undefined;
}

타입 서술어는 parameterName is Type 형태입니다.