Table of contents

6.8.0. Inroduction

템플릿 리터럴 타입은 문자열 리터럴 타입을 기반으로 하며, 유니온을 이용하여, 원하는 만큼, 타입으로 허용할 문자열의 개수를 늘릴 수 있다.

자바스크립트의 템플릿 리터럴 문자열과 같은 문법을 사용하지만, 타입을 작성하는 위치에서 사용된다는 점이 다르다. 콘크리트(프로그래밍에서는 구체적으로 구현된 이라는 뜻) 리터럴 타입(아래 예제의 World)과 함께 사용할 때, 템플릿 리터럴은 내용들을 연결지음으로써 새로운 문자열 리터럴 타입을 생성한다.

-template-literal-with-concrete.ts-

type World = 'world';

type Greeting = `hello ${World}`;

유니온 타입을 템플릿 리터럴 내에서 ${}와 함께 보간된(interpolated, 중간에 껴있는)위치에 넣으면, 각 유니온 멤버에 해당하는 모든 리터럴 타입을 갖는 새로운 유니온 타입을 반환한다.

-union-type-template-literal.ts-

type EmailLocaleIDs = 'welcome_email' | 'email_heading';
type FooterLocaleIDs = 'footer_title' | 'footer_sendoff';

type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
// type AllLocalIDs = 'welcome_email_id' | 'email_heading_id' | 'footer_title_id' | 'footer_sendoff_id'

각 템플릿 리터럴의 보간 위치에서, 유니온은 교차 곱셈 처리된다.

-union-type-template-literal.ts-

...
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
type Lang = 'en' | 'ja' | 'pt';

type LocalMessageIDs = `${Lang}_${AllLocaleIDs}`;
// type LocaleMessageIDs = "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" | "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" | "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"

일반적으로 위와 같이 개수가 많은 문자열 유니온은 사전에 생성하는 것을 권장하지만, 위와 같은 방식도 규모가 크지 않다면 유용하다 할 수 있다.

6.8.1. String Unions in Types

템플릿 리터럴의 진가는 타입 내에 존재하는 기존 문자열을 기반하여 새로운 문자열을 정의할 때 나타난다. 현재 가지고 있는 필드에 기반하여 새로운 오브젝트로 확장하는 패턴이 그 예다. 어떤 값이 변화하였을 때 이에 대한 알림을 주는 on 메서드 타입을 정의해보자. -string-unions-in-type.ts-

const person = makeWatchedObject({
	firstName: 'Saoirse',
	lastName: 'Ronan',
	age: 26
});

person.on('firstNameChanged', (newValue) => {
	console.log(`firstName was changed to ${newValue}`);
});