Typescript 템플릿 리터럴(Template Literals)

최정근·2023년 8월 2일
1

typescript

목록 보기
1/1
post-thumbnail

템플릿 리터럴(Template Literals)?

템플릿 리터럴은 백틱 기호를 사용하며 String Literal Type을 기반으로 다른 타입을 만들거나 String을 표현하는 문법입니다.
문자열 사이에 변수를 추가하려먼 + 기호를 통해 템플릿 로직을 구현해야 하지만 템플릿 리터럴은 하나의 문자열로 간편하게 구현 가능합니다.

  • Typescript4.1 이상
  • Javascript ES6 이상

리터럴 타입

Typescript에는 문자열, 숫자, boolean 세 가지 리터럴 타입이 있으며 union type, type guard 등 타입을 정의하는데 있어 enum과 유사한 기능을 제공합니다.
리터럴 타입으로 정의된 타입을 사용할 경우 허용된 값을 사용하지 않으면 오류가 발생하게 됩니다.

1. 문자열 리터럴 타입(String Literal Types)

type Market = 'opensea' | 'blur' | 'pala';

// market 값으로는 'opensea', 'blur', 'pala'만 사용할 수 있습니다.
function selectMarket(market: Market) {
  ...
} 

2. 숫자형 리터럴 타입(Numeric Literal Types)

type DiceNumber: 1 | 2 | 3 | 4 | 5 | 6;

// rollDice 함수의 return 값으로 1,2,3,4,5,6 중 하나가 나온다는 것을 예상할 수 있습니다. 
function rollDice(): DiceNumber {
  return (Math.floor(Math.random() * 6) + 1) as DiceNumber;
}

3. 부울 리터럴 타입(Boolean Literal Types)

아래 예시는 isSuccess의 값이 true일 경우 data의 값은 object타입이 올 수 있고 false일 경우 data는 어떠한 타입의 값도 올 수 없도록 만든 예시입니다.

type ResultSuccess {
  isSuccess: true;
  data: object;
}

type ResultFailure {
  isSuccess: false;
  data: never;
}

type Result = ResultSuccess | ResultFailure;

템플릿 리터럴 활용

1. 문자열 리터럴 타입 응용

다음과 같이 TopBottom, LeftRight를 조합하여 Align에 대한 하나의 타입을 만드는것 처럼 ${}를 사용해 중간에 다른 타입을 혼합하여 템플릿 리터럴을 만들 수 있습니다.

type TopBottom = 'top' | 'middle' | 'bottom'
type LeftRight = 'left' | 'center' | 'right'

type Align = `${TopBottom}-${leftRight}`;
/* 'top-left'   , 'top-cetner'   , 'top-right'
   'middle-left', 'middle-cetner', 'middle-right'
   'bottom-left', 'bottom-cetner', 'bottom-right' */

2. 멀티라인 리터럴(Multiline Literals)

  • 기존
    문자열 개행을 하려면 이스케이프 문자\를 사용하여 개행할 위치를 지정하고 다음 줄 처음에 \n을 넣어 구현합니다.

  • 멀티라인 리터럴
    엔터를 인식하여 개행을 처리합니다.

/*
Never gonna give you up
Never gonna let you down
*/
let hard = 'Never gonna give you up \
\nNever gonna let you down';

let easy = `Never gonna give you up
Never gonna let you down` ;

3. 문자열 보간(String Interpolation)

  • 기존
    문자열 중간에 다른 문자를 삽입할 때 기존에는 +를 사용하여 구현합니다.

  • 템플릿 리터럴
    ${}를 사용하여 중간에 문자를 삽입합니다.

let something = 'pen';

// I have a pen!!
let hard = 'I have a ' + pen + '!!' 
let easy = `I have a ${pen}!!`

4. 태그드 템플릿(Tagged Templates)

styled-components를 사용해 봤다면 익숙한 형태로, 함수를 사용할 때 함수명 뒤에 백틱 기호를 사용합니다.
Tagged Templates을 사용하면 문자열을 구성하는 단계에서 중간에 삽입하는 값에 따라 조건을 작성할 수 있습니다.

type Characters = 'Snow White' | 'The Queen';

function magicMirror(texts: TemplateStringsArray, ...characters: [Characters, Characters]) {
  let answer: string = 'No!!!';

  if (characters[0] === 'Snow White' && characters[0] === characters[1]) {
    answer = `Both ${characters[0]} and ${characters[1]} are pretty`;
  }
  else if (characters[0] === 'The Queen' && characters[0] === characters[1]) {
    answer = `Both ${characters[0]} and ${characters[1]} are ugly.`;
  }
  else if (characters[0] === 'Snow White' && characters[1] === 'The Queen') {
    answer = `${characters[0]} is more beautiful than ${characters[1]}.`;
  }

  return `Q: ${texts.join(' ')}
  A: ${answer}`;
}

const tautologyA = magicMirror`Mirror, mirror on the wall ! Is ${'Snow White'} prettier than the ${'The Queen'}?`;
/*
Q: Mirror, mirror on the wall ! Is Snow White prettier than the The Queen
A: Snow White is more beautiful than The Queen.
*/

const tautologyB = magicMirror`Mirror, mirror on the wall ! Is ${'The Queen'} prettier than the ${'Snow White'}?`;
/*
Q: Mirror, mirror on the wall ! Is The Queen prettier than the Snow White
A: No!!!
*/

위의 예시를 보면 Tagged Templates의 사용법은 다음과 같습니다.

function 함수명(texts: TemplateStringsArray, ...values: string[]) {
  return `${values[0]} ${texts[0]} ${values[1]}${texts[1]}`
}

const result = 함수명`${'a'} is ${'b'}.`;
// a is b
// texts = ['is', '.'];
// values = ['a', 'b']

첫 번째 파라미터 texts에는 ${}로 문자열을 split 한 결과가 들어있으며 두 번째 파라미터 values에넌 ${} 안의 값이 들어가게 됩니다.

이때, typescript에서는 values의 타입에 tuple을 적용해 개수를 제한할 수 있으며 타입 또한 명시하여 올 수 있는 타입을 제한할 수 있습니다.

type something = 'a' | 'b';

function 함수명(texts: TemplateStringsArray, ...values: [something, something]) {
  return `${values[0]} ${texts[0]} ${values[1]}${texts[1]}`
  // return `a is b.`
}

const result = 함수명`${'a'} is ${'b'}.`;
// ${}를 두 번 까지만 사용할 수 있으며 값으로는 something에 해당하는 값만 올 수 있습니다. 
profile
친절한 이웃 개발자

1개의 댓글

comment-user-thumbnail
2023년 8월 2일

좋은 글 감사합니다.

답글 달기