유니언 타입은 여러 타입 중 하나가 될 수 있는 값을 의미합니다. 세로 막대 (|)로 각 타입을 구분하여, number | string | boolean은 값의 타입이 number, string 혹은 boolean이 될 수 있음을 의미합니다.
function padLeft(value: string, padding: string | number) {
// ...
}
let indentedString = padLeft("Hello world", true);
유니언 타입인 값이 있으면, 유니언에 있는 모든 타입에 공통인 멤버들에만 접근할 수 있습니다.
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
declare function getSmallPet(): Fish | Bird;
let pet = getSmallPet();
pet.layEggs();
type NetworkLoadingState = {
state: "loading";
};
type NetworkFailedState = {
state: "failed";
code: number;
};
type NetworkSuccessState = {
state: "success";
response: {
title: string;
duration: number;
summary: string;
};
};
// 위 타입들 중 단 하나를 대표하는 타입을 만들었지만,
// 그것이 무엇에 해당하는지 아직 확실하지 않습니다.
type NetworkState =
| NetworkLoadingState
| NetworkFailedState
| NetworkSuccessState;
이 경우, 런타임에 나타나는 타입의 범위를 좁히기 위하여 switch문을 사용할 수 있습니다.
switch (state.state) {
case "loading":
return "Downloading...";
case "failed":
// 여기서 타입은 NetworkFailedState일 것이며,
// 따라서 `code` 필드에 접근할 수 있습니다.
return `Error ${state.code} downloading`;
case "success":
return `Downloaded ${state.response.title} - ${state.response.summary}`;
}
interface ErrorHandling {
success: boolean;
error?: { message: string };
}
interface ArtworksData {
artworks: { title: string }[];
}
interface ArtistsData {
artists: { name: string }[];
}
// 이 인터페이스들은
// 하나의 에러 핸들링과 자체 데이터로 구성됩니다.
type ArtworksResponse = ArtworksData & ErrorHandling;
type ArtistsResponse = ArtistsData & ErrorHandling;
const handleArtistsResponse = (response: ArtistsResponse) => {
if (response.error) {
console.error(response.error.message);
return;
}
console.log(response.artists);
};