TypeScript で 関数名の後ろに`string`←コレの正体

# TypeScriptでよくわからない書き方が発生した。

```typescript
const GlobalStyle = createGlobalStyle`
    ${restCss}
    body{
        margin : 0;
        padding: 0;
        box-sizing: border-box;
    }
`;
```
それはこのような物で、関数の後ろに直接 `` ` `` を使用して文字列を書いている。


## これなら理解できる。
```typescript
const GlobalStyle = createGlobalStyle(`
    ${restCss}
    body{
        margin : 0;
        padding: 0;
        box-sizing: border-box;
    }
`);
```

# 注意
このQiita記事を書きながら問題解決しているので、無駄に長くなっています。サッっと結果だけ知りたい方は[まとめ](#まとめ)を見たり[CodePen](https://codepen.io/lp0ql/pen/LYOZLVP?editors=1111)で触ったりしてみて下さい。

# この文法の正体

この文法の正体を教えて頂いたのでメモ。

- この文法の名前 : ``タグ付きテンプレートリテラル``



#  タグ付きテンプレートリテラルって何？

> タグ付きテンプレートは、テンプレートリテラルのより高度な形式です。

>タグを使用すると、テンプレートリテラルを関数で解析できます。タグ関数の最初の引数には、文字列リテラルの配列を含みます。残りの引数は式に関連付けられます。

>タグ関数は、これらの引数に対して何でも望み通りの操作を実行することができ、加工された文字列を返します。 (または、以下の例の一つで示しているように、まったく異なるものを返すこともできます。)

>タグに使用される関数の名前は、自由に指定できます。
[MDN タグ付きテンプレート](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals#tagged_templates)


## そもそもテンプレートリテラルって何？

>テンプレートリテラルは、組み込み式を扱うことができる文字列リテラルです。複数行の文字列や文字列挿入機能を使用することができます。

>ES2015 仕様書よりも前の版では、"template strings" と呼ばれていました。
[MDN テンプレートリテラル（テンプレート文字）](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals)

```typescript
// これの事っぽい。
`Hello world`

`Hello ${user.name}`
```

# タグって何？

つまり

```typescript
`Hello ${user.name}` + タグ = タグ付きテンプレートリテラル
```
になるらしい。

これで``タグ``が何か分かっていない事が分かった。

## タグ
（少し下に翻訳あり & 逆に混乱する情報の方が多いので、コレは一旦スキップで良い。）
>A tagged template (tag function) is what we call syntactic sugar. If you’ve never heard this term before it simply means that it’s syntax that was designed to make things easier to read.
With that in mind…A tagged template is a function call that uses a template literal from which to get its arguments.

>```javascript
// TAG FUNCTION
greet`I'm ${name}. I'm ${age} years old.`
```
A tag function is the function name ( greet ) followed by a template literal. Since our tag functions are purely syntactic sugar, using the above tag function, is equivalent to writing this normal function invocation:

>```javascript
// EQUIVALENT FUNCTION
greet(["I'm ", ". I'm ", " years old."], name, age)
```

>[JavaScript — What are Tag Functions?](https://codeburst.io/javascript-what-are-tag-functions-97682f29521b)
>>タグ付きテンプレート（タグ関数）は、シンタックスシュガーと呼ばれるものです。この用語を聞いたことがない場合は、単に読みやすくするために設計された構文であることを意味します。
それを念頭に置いて…タグ付きテンプレートは、引数を取得するためのテンプレートリテラルを使用する関数呼び出しです。

>>```javascript
// TAG FUNCTION
greet`I'm ${name}. I'm ${age} years old.`
```
タグ関数は、関数名（greet）の後にテンプレートリテラルが続くものです。タグ関数は純粋にシンタックスシュガーであるため、上記のタグ関数を使用することは、この通常の関数呼び出しを記述することと同じです。

>>```javascript
// EQUIVALENT FUNCTION
greet(["I'm ", ". I'm ", " years old."], name, age)
```

### タグ = タグ関数
この``タグ``と言うのは``タグ関数``という物の事だと思うので、

```typescript
`Hello ${user.name}` + タグ関数 = タグ付きテンプレートリテラル
```
になる。

# 結局``タグ付きテンプレートリテラル`` は何ができるの？
A.テンプレートリテラルを関数で処理する事ができる。

イメージ的には``Array.map``のテンプレートリテラル版だと思う。
<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="LYOZLVP" data-editable="true" data-user="lp0ql" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lp0ql/pen/LYOZLVP">
  タグ付きテンプレートリテラル</a> by lp0ql (<a href="https://codepen.io/lp0ql">@lp0ql</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

実際に``CodePen``で触ってみて理解した。

この``CodePen``で書いたようなシチュエーションで使うのは無駄だと思うけど、``タグ付きテンプレートリテラル`` で何が出来るのかはよく分かった。

# まとめ


```typescript
タグ関数 = Array.map のテンプレートリテラル版（イメージ）
テンプレートリテラル = `${a}は${b}です。` // こんなやつ
タグ付きテンプレートリテラル = タグ関数 に対して タグ付きテンプレートリテラル を使う事
```

## 実装方法

### タグ関数を作る

```typescript
const tagFunction = (handles:string[], values:string[]):string => {
  return "あいうえお"
} 
```

``handles`` に ``${}``の外の文字列
``values`` に ``${}`` の中の値が入っている。

これらの値を使って``return``する文字列を作る

### タグ関数を使う
```typescript
const displayString = tagFunction`${a}と${b}`;

console.log(displayString);
// => あいうえお
```