Ayden's journal

Tagged Template Literal

Tagged Template Literal 혹은 태그된 템플릿 리터럴이라 불리는 문법은 ES6부터 지원되는 자바스크립트 기능으로, 템플릿 리터럴을 함수와 함께 사용하여 더 강력하게 값을 조작할 수 있게 한다. 기본 템플릿 리터럴은 문자열을 표현하는 데 쓰이지만, 태그를 사용하면 문자열의 각 부분과 값들을 원하는 대로 가공할 수 있다. 태그 함수는 일반 함수와는 다르게 템플릿 리터럴 바로 앞에 위치해, 해당 함수가 템플릿을 처리하게 된다.

기본적으로 태그 함수의 타입은 아래와 같다. 템플릿 리터럴로 무엇이 올지 모른다는 점 때문에 unknown으로 선언했지만, 필요하다면 Array<string | number> 타입과 같은 방식으로 정해진 타입만을 받을 수도 있다.

function myTag(strings: TemplateStringsArray, ...values: Array<unknown>): string {}

 

프론트엔드 개발자에게 있어서 태그된 템플릿 리터럴을 보자마자 떠오르는 사례는 아마도 styled-component의 styled 함수일 것이다. 이 태그 함수는 여러 다양한 css를 받아서 컴포넌트를 리턴한다. 또 다른 예시는 Apollo Client나 graphql-request 에서 제공하는 쿼리 함수 gql가 있겠다.

 

 

한 가지 기억해둘만한 것은 strings의 길이는 언제나 values보다 하나 더 길다는 것이다. 변수 두 개를 사용할 경우 strings의 길이는 3이 된다. 이는 특정한 문자를 기준으로 문자열을 split하면 반드시 해당 문자에 1을 더한 만큼의 배열이 나오는 것과 비슷하다고 할 수 있겠다.

"가나다나가".split("나"); // ["가", "다", "가"]

const 나 = "나";
myTag`가${나}다${나}가`; // strings : ["가", "다", "가"]
                      // values : ["나", "나"]

 

내가 생각할 수 있는 태그된 템플릿 리터럴의 활용 방안은 아래와 같다. 들어오는 변수들에 대한 값을 확인하고 이것들에 대한 비교를 할 수 있지 않을까? 또, [Object object] 대신 객체 내부의 값을 꺼내서 쓸 수도 있으니 사용하기에 따라 굉장히 유용하리란 생각이 든다.

function score(strings: TemplateStringsArray, name: string, ...values: Array<number>) {
  if (values[1] + values[2] + values[3] !== values[0]) {
    throw new Error("세 과목에서 받은 점수의 합이 총 점수와 다릅니다.")
  }

  return strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "");
}

score`학생 ${name}이 시험에서 받은 점수의 총 합은 ${totalPoint}으로 국어, 영어, 수학에서 각각 ${koreanPoint}, ${EnglishPoint}, ${MathPoint} 점을 획득하였습니다.`

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기