type Literal = 'literal';
type Template = `template ${Literal}`; //"template literal"
// Template 타입을 사용하면 정해진 문자열만 변수에 대입할 수 있음
const str: Template = 'template literal';
type Template = `template ${string}`;
let str: Template = 'template ';
str = 'template hello';
str = 'teamplte 123';
str = 'template'; // error -> template 문자열 뒤에 띄어쓰기가 없기 때문
type City = 'seoul' | 'suwon' | 'busan';
type Vehicle = 'car' | 'bike' | 'walk';
type ID = `${City}:${Vehicle}`;
const id = 'seoul:walk';
type RemoveX<Str> = Str extends `x${infer Rest}`
? RemoveX<Rest>
: Str extends `${infer Rest}x` ? RemoveX<Rest> : Str;
type Removed = RemoveX<'xxtestxx'>; // 'test'
어떤 타입을 만든 뒤에는 여러 테스트 사례를 생각해서 어떠한 경우에도 다 돌아가도록 만들어야 한다.
type RemovedEmpty<Str> = Str extends ` ${infer Rest}`
? RemovedEmpty<Rest>
: Str extends `${infer Rest} ` ? RemovedEmpty<Rest> : Str
TYPE REMOVED = REMOVEEMPTY<' test '> // 'test'