Search code examples
javascripttemplate-literals

How to write String.raw() with normal JavaScript code


According to MDN,

String.raw() is the only built-in template literal tag. It has close semantics to an untagged literal since it concatenates all arguments and returns a string. You can even re-implement it with normal JavaScript code.

How would you "re-implement String.raw() with normal JavaScript code"? If I write my own template literal function const raw = (s, v) => ..., the string array s contains strings that are no longer raw. For example,

raw `a\nb`

will pass a-newline-b, whereas the raw string would be a-backslash-n-b.

My raw() template literal function could reverse the quoting by turning newline into backslash-n, but that's not reliable. How does it distinguish between:

raw `a\nb`

and

raw `a
b`

?


Solution

  • The array that is passed as first argument to the template tag function has an additional property raw, as documented here. It contains the same as strings itself but as raw strings, without parsing escape sequences.

    This means that String.raw could be replicated as follows:

    function myRaw (strings, ...values) {
      return strings.raw.reduce((result, s, i) => result + s + (values[i] ?? ''), '')
    }
    

    Note that if we'd replace strings.raw.reduce with just strings.reduce, we'd get a "do-nothing" template tag function.