Nuxt.jsでTypeScript 3.7を使う

# 2019/12/18追記

12/12にBabelを取り除きTypeScriptのみでTypeScript 3.7の新機能に対応した[`@nuxt/typescript-build@0.5.1`](https://github.com/nuxt/typescript/releases/tag/%40nuxt%2Ftypescript-build%400.5.1)がリリースされました。

Babel削除に伴い、`tsconfig.json`の`target`を`es2018`に指定しないと、`vue-loader`がOptional ChainingやNullish Coalescingを解析できなくなりました。
そのため、TypeScriptの時点でPolyfill込みのトランスパイルを行う必要があります。

```
SyntaxError: /path/to/project/component.vue: Support for the experimental syntax 'optionalChaining' isn't currently enabled (30:28):

  29 |         const obj = { foo: 1 };
> 30 |         console.log(obj.bar?.baz?.qux);
     |                            ^

Add @babel/plugin-proposal-optional-chaining (https://git.io/vb4Sk) to the 'plugins' section of your Babel config to enable transformation.
```

```diff
{
  "compilerOptions": {
-    "target": "esnext"
+    "target": "es2018"
  }
}
```

なお、`@nuxt/typescript-build@0.5.1`以降は`tsconfig.json`の`target`指定以外に特別な対応は不要となりました。

## 手動アップグレード分を削除する

追記前の状態では、手動で関連パッケージをインストールしているため、今後バージョンの乖離が起こる可能性があります。そのため、手動アップデート分のパッケージ情報を`package.json`から削除することをおすすめします。

```sh
$ yarn remove typescript ts-node ts-loader @babel/plugin-proposal-nullish-coalescing-operator @babel/plugin-proposal-optional-chaining
```

# 2019/12/09追記

本日リリースされた[`@nuxt/typescript-build@0.4.0`](https://github.com/nuxt/typescript/releases/tag/%40nuxt%2Ftypescript-build%400.4.0)と[`@nuxt/typescript-runtime@0.3.0`](https://github.com/nuxt/typescript/releases/tag/%40nuxt%2Ftypescript-runtime%400.3.0)でTypeScript 3.7が正式にサポートされました 🎉

これらのバージョンを使用していれば、以降の[Babelプラグインの追加](#babelプラグインの追加)以外の設定は不要となります。

[Babelプラグインの追加](#babelプラグインの追加)自体はNode側プロセスで必要みたいなので対応しなければならなようです。

## 手動アップグレード分を削除する

以降の手順を試された方は、今後のアップデートでバージョンの乖離が起きないよう、手動アップグレードした`typescript`と`ts-node`、`ts-loader`を`package.json`から削除しておくことをおすすめします。

```sh
$ yarn remove typescript ts-node ts-loader
```

# はじめに

2019/11/18現在、Nuxt.jsではTypeScript 3.7を使用することはできません。

ただし、使用しているパッケージのバージョンを手動で変更すればTypeScript 3.7に対応することができるようです。

ここでは、その手順をご紹介します。

# 開発環境での設定

## パッケージのバージョンアップ

手動で以下のパッケージをバージョンアップします。

* `@nuxt/typescript-runtime`
* `@nuxt/typescript-build`
* `ts-node`
* `ts-loader`
* `typescript`

```sh
$ yarn add "@nuxt/typescript-build@^0.3.4"
$ yarn add -D \
  "@nuxt/typescript-runtime@^0.2.4" \
  "ts-node@^8.5.0" \
  "ts-loader@^6.2.1" \
  "typescript@^3.7.2"
```

## Babelプラグインの追加

TypeScript 3.7から追加された文法上の新機能である `Optional Chaining` と `Nullish Coalescing` はそのままでは実行することができません。

* `@babel/plugin-proposal-nullish-coalescing-operator`
* `@babel/plugin-proposal-optional-chaining`

そのため、Babelプラグインを追加してトランスパイルされるようにします。

```sh
yarn add -D \
  @babel/plugin-proposal-nullish-coalescing-operator \
  @babel/plugin-proposal-optional-chaining
```

これら２つのプラグインをBabelの設定に追加します。

```ts
// nuxt.config.ts
const config: Configuration = {
  build: {
    babel: {
      plugins: [
        '@babel/plugin-proposal-nullish-coalescing-operator',
        '@babel/plugin-proposal-optional-chaining',
      ],
    },
  },
};

moodule.exports = config;
```

以上で、TypeScript 3.7を使ってNuxtアプリがビルドできるようになりました 🎊

# VSCodeでの設定

VSCodeでTypeScript 3.7を用いたVueアプリの開発を行うためには少し設定が必要です。

## `.ts`ファイル

`.ts`ファイルの場合は、右下のTypeScriptバージョンを`3.6.3`から`ワークスペースのバージョン (3.7.2)`に変更すればTypeScript 3.7の新機能でもエラーが発生しなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/73594c50-bdf8-3fcd-1905-98888e9ac927.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/dd155965-7c53-5c05-31f6-b36688665a16.png)

## `.vue`ファイル

`.vue`ファイルの場合はVeturの設定を変更する必要があります。

`vetur.useWorkspaceDependencies`にチェックを入れると、ワークスペースのTypeScriptをVeturが参照するため、`3.7.2`の新機能を使用できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/d938f538-21dd-9c12-0865-b3375ead9f80.png)

# 参考

* [TypeScript 3.7 support · Issue #185 · nuxt/typescript](https://github.com/nuxt/typescript/issues/185)
* [TypeScript 3.7.2がリリースされました！Optional ChainingやNullish Coalescingをさっそく使ってみた ｜ Developers.IO](https://dev.classmethod.jp/client-side/typescript-3-7-2-release/#toc-visual-studio-codevs-code)
* [VeturにTypeScript3.7のOptional Chainingを適用してみる - Qiita](https://qiita.com/ibara1454/items/10d6091858db106e717b)