{ES/TS} bit of the day: Typed Tagged Templates
Tags: typescript, taggedtemplates, es6
Published: 2018-12-28 16:55:19

---
title: {ES/TS} bit of the day: Typed Tagged Templates
published: true
description: A simple introduction to type tagged templates, with react and typescript applications
tags: typescript, tagged-templates, es6
---


Hi there! Today I'd like to talk about one of my beloved `modern` javascript features. These are Tagged Templates.

## Tagged What?

Basically Tagged Templates are an extension of the basic interpolation mechanism that you normally uses in ES6+.

Using `backticks` you can elegantly insert values in a string (multiline by the way, :-))

```js
const greet = (name) => `hello ${name}`

greet('timothee') // hello timothee
```

In one work? 

By **using the backticks notation with a function identifier**, you basically have a template engine for free.

## An example please!

Don't worry, it's actually less scary than what it sounds.

Let's take a function like

```js
function myTemplate() {}
```

We'll see the actual arguments later.

I can call the function with this syntax now.

```js
myTemplate`Hello !`
```

Weird isn't it?

What's more interesting, is I can actually pass interpolations with the familiar `${}` syntax.

Let's try it:

```js
const externValue = "Timothee"
myTemplate`Hello ! ${externValue}`
```

Of course, I now can use computed values from the surrounding scope of my function call.

This syntax is **an actual function call of myTemplate**

## So what's the magic actually?

Let's see the arguments passed to the function:

- The first argument is a list of invariant strings
- the `n` others arguments are all the other interpolation produced by `${}` usage.

For instance, if I make this call:

```js
myTemplate`Hello,${"Timothee"},World`
```

The first argument will be a list of all strings that don't change inside the passed string:

```js
["Hello,", ",World"]
```

Of course, if you don't use any interpolations, you will have one element inside this array, the entire passed string.

The next argument will be my first interpolation, here it's a constant string: `Timothee`.

So if we have `n` interpolation in our template string, we all have `n+1` elements in our first array, and `n` more arguments passed to the function.

## Cool, but how is it useful?

Whenever you need to apply transformations to a string with interpolation (aka dynamic values), this can be very useful.

For instance, you could build a  template engine respecting the native semantics of es6

```js
html`<h1>Hello ${name}</h1>`;
```

Actually, this already exists: https://lit-html.polymer-project.org/

In the react context, this technique is used to generate pre-styled components from CSS code for CSS-in-js solutions as `emotion` or `styled-components`.

```js
const PrestyledComponent = styled('div')`
/** real css here */
background-color: blue;
`

// usage
const Fragment = <PrestyledComponent />

```

## How can we type tagged templates

In typescript, we can add type information to our tagged templates:

```ts
function tagged(strings: TemplateStringsArray, ...args: boolean[]){
  console.log(args)
}
```

The idea is to type the **first** argument as the `TemplateStringsArray` type and the subsequent interpolations to whatever you need.


Let's take an example. Let's say you want to have auto-completable access to your theme from a `styled component`

```ts
export const theme = {
  'colors.hello': true
}

export type ThemeKeys =  keyof typeof theme


function themedStyled(strings: TemplateStringsArray, ...args: ThemeKeys[]){
  console.log(args)
}


themedStyled`
  background-color: ${};
`
```

And you got auto-completion of your theme keys for free!

![Autocompletion](https://i.imgur.com/vbdKAZq.jpg)


That's it for today. Till next time!