템플릿 리터럴 타입은 문자열 리터럴 타입으로 만들어졌고, 여러개의 문자열을 유니언을 통해 확장할 수 있다.
이를테면,
type World = 'World';
type Greeting = `hello ${World}`;
와 같이 템플릿 리터럴을 사용하여 Greeting의 타입을 ‘Hello World’ 로 만들 수 있다.
유니언을 적용하여 이를테면
type Head = 'Alpha' | 'Beta';
type Tail = 'Gamma' | 'Delta';
type LiteralType = `${Head | Tail} type`; //Alpha type | Beta type | Gamma Type | Delta Type
처럼 만들수도 있다.
내부에 템플릿 리터럴을 여러개 사용할 경우
type Lang = 'EN' | 'KR';
type Messages = 'WELCOME' | 'GOODBYE';
type LiteralType = `${Lang}_${Messages}`; //"EN_WELCOME" | "EN_GOODBYE" | "KR_WELCOME" | "KR_GOODBYE"
처럼 사용할 수 있다.
한편, 말 그대로 집어넣은 템플릿 리터럴 내부의 값이 ‘타입’ 이기에,
다음과 같이 리터럴 앞뒤의 타입을 강제할 수 있는데
type LiteralType = `test_${number}`;
const testOne: LiteralType = 'test_1';
const testTwo: LiteralType = 'test_two'; //ERROR
위와 같이 test_ 뒤에 특정 타입만 올 수 있도록 강제할 수 있다.
혹은
type J = {
size: number;
}
type PropEventSource<Type> = {
on(eventName: `${string & keyof Type}Changed`, callback: (newValue: any) => void): void;
};
위와 같은 상황에서
const testSource: PropEventSource<J> = {
on: function(eventName: "sizeChanged", callback: (newValue: any) => void): void {
throw new Error("Function not implemented.");
}
};
다음과 같이 eventName을 특정 이벤트 타입 이름으로 지정해줄 수 있다.
템플릿 리터럴을 사용해서 문자열을 조작할 수 있는데,
type RemoveMinus<T> = T extends `-${infer J}` ? J : T;
type NonMinus = RemoveMinus<'test'>; //test
type YesMinus = RemoveMinus<'-test'>; //test
위와 같이 문자열 앞에 달려있는 - 를 지울 수 있다.
혹은, 더하기를 앞에 하나 붙이는 경우에도
type AddPlus<T extends string> = T extends `+${infer J}` ? T : `+${T}`;
type AlreadyPlus = AddPlus<'+test'>; //+test
type NoPlus = AddPlus<'test'>; //+test
처럼 할 수 있다.