Template literals and tagged template literals

ashutoshbw

Ashutosh Biswas

Posted on March 18, 2022

Template literals and tagged template literals

Template literals are a handy way to include any values inside of a string. With template literal you always get a string value. Tagged template literals give you complete freedom over the return value of a template literal and gives you access to the parts of it through a function called the tag function.

Here we will take an in-depth look at both of them. But I will not include the practical usages and examples of tagged template literals so that we can focus on how it works very well without becoming overwhelmed. After going through this article you will have all the required knowledge of it to study any of it's practical examples.

Let's start exploring.

Bird eye view

First let's take a bird eye view of both of them.

Template literals(aka untagged template literals)

let n = 9;
let squareStr = `The square of ${n} is ${ n * n }.`; 
console.log(squareStr);
// The square of 9 is 81.

let poem = 
`
from my bed
I watch
3 birds
on a telephone
wire.
  -- Charles Bukowski 
`;
console.log(poem)
// output
/*
from my bed
I watch
3 birds
on a telephone
wire.
  -- Charles Bukowski 
*/
Enter fullscreen mode Exit fullscreen mode

Tagged template literals(aka tagged templates)

With tagged templates we can get access to the individual parts of a template literal and return any value we wish!

For this we need a function to tag to the template literal:

function highlightInsertedParts(templateStrings, ...substitutions) {
  // console log to see what's in templateStrings and substitutions

  let result = templateStrings[0];
  for (let i = 1; i < templateStrings.length; i++) {
    result += `πŸ‘‰${substitutions[i - 1]}πŸ‘ˆ${templateStrings[i]}`;
  }
  return result;
}
Enter fullscreen mode Exit fullscreen mode

If the ...substitution is syntax is new to you, here is your short guide: It says pack the rest of the arguments given to the function highlightInsertedParts into an array called substitution.

Now we can tag this function to a template literal to create tagged template literal:

highlightInsertedParts`${1}`; 
// 'πŸ‘‰1πŸ‘ˆ'

highlightInsertedParts`This is ${'cool'}.`  
// 'This is πŸ‘‰coolπŸ‘ˆ.'
Enter fullscreen mode Exit fullscreen mode

If this you don't understand it fully, don't worry. This example will make full sense, once you go through this article.

Deep dive

Template literal

Template literal

Template literal(aka untagged template literal) is somewhat like a string literal. It's written within backticks(`). It's value is always a string. It gives the following unique advantages that string literals don't give us:

Firstly, string interpolation. We can place any expression in it within ${ } which is called a placeholder. The given expression within it is called a substitution. A placeholder must contain a substitution. The each chunk of text seperated by placeholders are called template strings. JavaScript evaluates the substitutions and in this process converts them to strings if they are not and joins all of it's individual parts in respective order to return a string value. For example:

`Let's put an array: ${[1, `${ [2.1, 2.2] }`, 3]}!`
// it will return:
"Let's put an array: 1,2.1,2.2,3!"
Enter fullscreen mode Exit fullscreen mode

Note that, the feature that substitution can be any JavaScript expression allows to compose nested template literals!

Secondly, multiline strings. Now we can write multiline string just by creating real newline in code:

`
A line
A new line
`
Enter fullscreen mode Exit fullscreen mode

Note that if you want to get backtick or a placeholder in the output of template literals literally, we need to escape them with backslash(\):

`\`This is a \${'template'} literal too\``
// output
"`This is a ${'template'} literal too`"
Enter fullscreen mode Exit fullscreen mode

Tagged template literal

Tagged template literal is also called tagged template for short.1 It's syntax is like below:

expression`template literal`
Enter fullscreen mode Exit fullscreen mode

Tagged template has two parts:

  1. expression: This is an expression which must evaluate to a function. This function is called tag function.
  2. `template literal`: It can be any template literal. The only difference is that we don't get any joined string value like before.

A tag function gets the access to it's template literals each part through it's arguments. The return value of this function is the value of the tagged template.

Cooked and raw interpretation of template strings

To understand the tag function properly we need to understand two more things: the cooked and raw interpretation of template strings, because tag function gives us access to both forms.

  • Cooked interpretation means the backslashes have special meaning. For example \n will produce a single character which is a newline character.
  • Raw interpretation means backslashes don't have special meaning. So \n will produce two characters: \ and n.

Tag function

Finally we have reached to the heart of tagged template, the tag function. JavaScript gives us access to the parts of it's template literal thorough it's arguments like below:

  • 1st argument: This is an array holding the cooked interpretation of template strings. However if a template string holds incorrect syntax of the following kind of escape sequences then the corresponding array element of that template string will hold undefined.

    • Unicode codepoint escapes (eg. \u{1F642})
    • Unicode unit escapes (eg. \u03A3)
    • Hexadecimal escapes (eg. \x41)

    This array has a raw named property which holds all the raw interpretation of the template strings. (If untagged template literal or string literal holds incorrect syntax of the above escape sequences, JavaScript will throw error.)

  • Remaining arguments: These are the substitutions.

The return value of tag function is the value of the tagged template. This value can be anything.

That's it. Now you know all the theories 😎 Do the quizzes to make sure you know it really well.

Quizzes

To match your answers with mine checkout my original blog post.

Run code in brain

What will the output of the following codes?

'\unicode is awesome'
`\unicode is awesome`
Enter fullscreen mode Exit fullscreen mode

What will be the output of the following line?

((...args) => args[0].raw[0])`\unicode is awesome`
Enter fullscreen mode Exit fullscreen mode

How is it possible?

["one", "two", "three"].join` -> `.concat` ---> πŸ’₯`
// 'one -> two -> three ---> πŸ’₯'
Enter fullscreen mode Exit fullscreen mode

What is the length of 1st argument of tag function(which is an array)?

If there are n substitutions, what is the length of the array that we get as the first argument of tag function?

Further study

For digging more or to study practical usages, here are some good resources:

If this article helped you, please buy me a coffee:
Buy Me A Coffee


  1. ExploringJS ↩

πŸ’– πŸ’ͺ πŸ™… 🚩
ashutoshbw
Ashutosh Biswas

Posted on March 18, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related