유니온 타입(Union Type)이란 자바스크립트의 OR 연산자(||)와 같이 A이거나 B이다 라는 의미의 타입입니다.
type News = {
id: number;
time_ago: string;
title: string;
url: string;
user: string;
content: string;
};
// Intersection Type
type NewsFeed = News & {
comments_count: number;
points: number;
// optional properties
read?: boolean;
};
type NewsDetail = News & {
comments: NewsComment[];
};
// 함수 getData의 반환값을 Union Type으로 지정
function getData(url: string): NewsFeed[] | NeswDetail {
ajax.open("GET", url, false);
ajax.send();
return JSON.parse(ajax.response);
}
// 함수 getData가 사용되는 두가지 상황 발생
// 1. NewsFeed[]를 반환하는 함수 newsFeed
// 2. NeswDetail을 반환하는 함수 newsDetail
function newsFeed(): void {
...
if (newsFeed.length === 0) {
// 불러온 뉴스 데이터에 read 속성을 추가함
newsFeed = store.feeds = makeFeeds(getData(NEWS_URL));
console.log("makeFeeds read =>", newsFeed);
}
}
function newsDetail(): void {
const id = location.hash.substring(7);
const newsContent = getData<NewsDetail>(CONTENT_URL.replace("@id", id));
...
}
function getData(url: string): NewsFeed[] | NeswDetail {}
function getData(url: string): NewsFeed[] | NewsDetail
'NewsFeed[] | NewsDetail' 형식의 인수는
'NewsFeed[]' 형식의 매개 변수에 할당될 수 없습니다.
'NewsDetail' 형식에 'NewsFeed[]' 형식의
length, pop, push, concat 외 29개 속성이 없습니다.ts(2345)
이에, 어느 타입이 들어오든 우류가 나지 않는 방향으로 타입을 추론하게 되기 때문에, NewsFeed[] 과 NewsDetail 두 타입에 공통으로 들어있는 속성인 News 타입 속성만 접근할 수 있습니다.
참고 : 타입스크립트 핸드북
함수 getData는 리턴 값을 2가지 종류를 갖고 있습니다.
그러나, getData를 사용하는 입장에서는, 어떤 값이 올지 예상할 수 없는 상황입니다.
제네릭은 C#, Java 등의 언어에서 재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 특징입니다. 특히, 한가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트를 생성하는데 사용됩니다.
출처 : 타입스크립트 핸드북
제네릭은 입력이 n개의 유형일 때, 출력도 n개의 유형인 것을 정의하는 것입니다.
여기서 핵심은 입력이 ABCD 유형 중, A가 입력되면 출력도 A로 나가야합니다.
이러한 상황을 제네릭이라는 문법으로 표현할 수 있습니다.
function getData<AjaxRespons>(url: string): AjaxRespons {
ajax.open("GET", url, false);
ajax.send();
return JSON.parse(ajax.response);
}
함수의 이름 바로 뒤에 "T" 라는 코드를 추가하고, 함수의 인자와 반환 값 모두에 "T" 라는 타입을 추가합니다.
이때, "T" 는 통상적인 이름이며, 명시적으로 지정하는 것이 가독성을 높혀 줄 수 있습니다. 여기서는 "T" 대신 "AjaxRespons" 로 작명 했습니다.
또한, 위 코드에서는 반환 값 타입만 지정해줬습니다. 이유는 제네릭의 특성 상, 입출력 타입이 모두 동일하기 때문에, 인자 타입을 생략했습니다.
if (newsFeed.length === 0) {
// 불러온 뉴스 데이터에 read 속성을 추가함
newsFeed = store.feeds = makeFeeds(getData<NewsFeed[]>(NEWS_URL));
console.log("makeFeeds read =>", newsFeed);
}
function newsDetail(): void {
const id = location.hash.substring(7);
const newsContent = getData<NewsDetail>(CONTENT_URL.replace("@id", id));
...
}
제네릭이 적용된 함수 getData를 호출 할 때, 기술된 타입이 그대로 "AjaxRespons 타입" 에 적용되고, 리턴 값을 "AjaxRespons 타입"으로 출력합니다.
즉, 호출하는 쪽에서 타입을 명시해 주면, 그 타입을 적용해서 그대로 getData의 반환 타입으로 사용하겠다는 것이 제네릭입니다.