Skip to content

What is the default “tag” function for template literals?

What is the name of the native function that handles template literals?

That is, I know that when you write tag`Foo ${'bar'}.`;, that’s just syntactic sugar for tag(['Foo ', '.'], 'bar');

But what about just ​`Foo ${'bar'}.`;? I can’t just “call” (['Foo ', '.'], 'bar');. If I already have arguments in that form, what function should I pass them to?

I am only interested in the native function that implements the template literal functionality. I am quite capable of rolling my own, but the purpose of this question is to avoid that and do it “properly”—even if my implementation is a perfect match of current native functionality, the native functionality can change and I want my usage to still match. So answers to this question should take on one of the following forms:

  1. The name of the native function to use, ideally with links to and/or quotes from documentation of it.

  2. Links to and/or quotes from the spec that defines precisely what the implementation of this function is, so that if I roll my own at least I can be sure it’s up to the (current) specifications.

  3. A backed-up statement that the native implementation is unavailable and unspecified. Ideally this is backed up by, again, links to and/or quotes from documentation, but if that’s unavailable, I’ll accept other sources or argumentation that backs this claim up.


  1. Actually, the first argument needs a raw property, since it’s a TemplateStringsArray rather than a regular array, but I’m skipping that here for the sake of making the example more readable.

Motivation

I am trying to create a tag function (tag, say) that, internally, performs the default template literal concatenation on the input. That is, I am taking the TemplateStringsArray and the remaining arguments, and turning them into a single string that has already had its templating sorted out. (This is for passing the result into another tag function, otherTag perhaps, where I want the second function to treat everything as a single string literal rather than a broken up template.)

For example, tag`Something ${'cooked'}.`; would be equivalent to otherTag`Something cooked.`;.

My current approach

The definition of tag would look something like this:

function tag(textParts, ...expressions) {
  const cooked = // an array with a single string value
  const raw = // an array with a single string value
  return otherTag({ ...cooked, raw });
}

Defining the value of raw is fairly straightforward: I know that String.raw is the tag function I need to call here, so const raw = [String.raw(textParts.raw, ...expressions)];.

But I cannot find anywhere on the internet what function I would call for the cooked part of it. What I want is, if I have tag`Something ${'cooked'}.`;, I want const cooked = `Something ${cooked}.`; in my function. But I can’t find the name of whatever function accomplishes that.

The closest I’ve found was a claim that it could be implemented as

const cooked = [expressions.map((exp, i) => textParts[i] + exp).join('')];

This is wrong—textParts may be longer than expressions, since tag`Something ${'cooked'}.`; gets ['Something ', '.'] and ['cooked'] as its arguments.

Improving this expression to handle that isn’t a problem:

const cooked = [
  textParts
    .map((text, i) => (i > 0 ? expressions[i-1] : '') + text)
    .join(''),
];

But that’s not the point—I don’t want to roll my own here and risk it being inconsistent with the native implementation, particularly if that changes.

Answer

The name of the native function to use, ideally with links to and/or quotes from documentation of it.

There isn’t one. It is syntax, not a function.

Links to and/or quotes from the spec that defines precisely what the implementation of this function is, so that if I roll my own at least I can be sure it’s up to the (current) specifications.

Section 13.2.8 Template Literals of the specification explains how to process the syntax.