ts migrateを使ってReactのアプリをJavaScriptからTypeScriptに書き換えよう！！

皆さんこんにちは。

最近、毎日の様にTypeScriptという単語が耳に入ってきて、「TypeScriptって伸びてるみたいだし、そんなにいいのか」と思い、いろいろ調べていたのですが、どうやらなかなかに良さそうな言語だったので、基礎的な部分を少し勉強してみました。

そこで、「試しにReactのアプリもjsxからtsxに置き換えてみるか」と思い、調べていると`ts migrate`という、Airbnbが開発したパッケージがあり、これを利用するのが良さそうだとわかったので、試しに使ってみたところめっちゃ便利だったので、今回は`ts migrate`についての使い方の記事を書こうと思いました。

## ts migrateってなに？
ts migrateの[公式リポジトリ](https://github.com/airbnb/ts-migrate)の説明によれば、

>ts-migrate はコードの TypeScript への移行を支援するツールです。JavaScript、または部分的な TypeScript プロジェクトを取り込み、コンパイルした TypeScript プロジェクトを出力します。ts-migrate は TypeScript の移行プロセスを高速化することを目的としています。結果として得られるコードはビルドを通過しますが、型の安全性を向上させるためのフォローアップが必要です。たくさんの // @ts-expect-error や、時間をかけて修正する必要があるものがあるでしょう。一般的には、ゼロから始めるよりもずっといいでしょう。

とのことです。

まとめると、

- TypeScriptへの移行ツール
- TypeScriptへの移行を(手作業と比べて)高速化することが目的
- しかし、変換されたコードは型の安全性が低いので修正が必要

こんな感じです。

少し補足すると、`コマンド一発で選択したディレクトリ配下のjsファイルを全てtsファイルに変換し、中身の関数などにも型をつけてくれるもの`です。
ただ、型は全て`any`なので後から変えていく必要があるよ、ということです。

## 実際に使ってみる
さて、実際に使ってみましょう。

以下の`使い方`のところで出てきますが、先にgitをクリーンな状態にしておきましょう。ローカルでの変更がremoteにcommitされているかmasterが最新の状態になっているか確認しましょう。

確認ができたら、作業用のブランチを切ります。

```console
$ git checkout -b ts-migrate
```

### インストール
インストールは簡単です。

npmの場合は
 
```console
$ npm i ts-migrate
```
yarnの場合は

```console
$ yarn add ts-migrate
```

これで、インストール完了です！

### 使い方
以下のコマンドで、ファイルをTS化できます。

```console
$ npx ts-migrate-full <folder>
```
この<folder>の部分は変換したいフォルダを選択します。今回は、Reactのsrcフォルダ配下のファイルをtsx化したいので、

```console
$ npx ts-migrate-full src
```
として実行します。
実行すると、以下の様なとても親切なメッセージが表示されます。

```console
This script will migrate a frontend folder to a compiling (or almost compiling) TS project.

It is recommended that you take the following steps before continuing...

1. Make sure you have a clean git slate.
   Run `git status` to make sure you have no local changes that may get lost.
   Check in or stash your changes, then re-run this script.

2. Check out a new branch for the migration.
   For example, `git checkout -b ts-migrate` if you're migrating several folders or
   `git checkout -b ts-migrate-src` if you're just migrating src.

3. Make sure you're on the latest, clean master.
   `git fetch origin master && git reset --hard origin/master`

4. Make sure you have the latest npm modules installed.
   `npm install` or `yarn install`

If you need help or have feedback, please file an issue on Github!

Continue? (y/N)
```

訳すと、

1. git をクリーンな状態にしておきましょう。git status` を実行して、ローカルでの変更が失われていないことを確認します。チェックインするか変更を保存してから、このスクリプトを再実行します。
2. 移行のための新しいブランチをチェックアウトします。例えば、複数のフォルダを移行する場合は `git checkout -b ts-migrate` とします。srcを移行するだけなら `git checkout -b ts-migrate-src`。
3.  最新のクリーンなマスターを使用していることを確認してください。`git fetch origin master && git reset --hard origin/master` です。
4. 最新の npm モジュールがインストールされていることを確認してください。`npm install` または `yarn install` を実行する。

全部OKならyを入力。
変換が開始されます。

```console
All done!

The recommended next steps are...

1. Sanity check your changes locally by inspecting the commits and loading the affected pages.

2. Push your changes with `git push`.

3. Open a PR!
```
いろいろログが出た後に、上記の様に`All done!`とでていれば成功です。

ちゃんと変換ができています！！(感動)
jsxファイルは以下の様にtsxファイルになりました。
![スクリーンショット 2020-12-08 12.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/2528ca8b-4eb8-c54c-226d-5fa1c4269900.png)

関数コンポーネントも

```Post.tsx
const Post = ({content, createdAt, title,  uid}: any) => {
//以下省略
```
この様に型がつけられています🎉

### typescriptをインストールしていない場合はインストール

```console
npm install typescript
```

### tsconfigの設定

tsconfigは以下の様に設定しました。

```tsconfig.json
{
  "compilerOptions": {
    "jsx": "react",
    "target": "es5",
    "module": "esnext",
    "strict": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": [
    "src"
  ]
}
```

### いろいろなerrorを消していこう
簡単に変換はできましたがいろいろerrorが出るので、それらを直していきます。

よくあるのは、`@ts-expect-error`です。

この`@ts-expect-error`がコメントで表示されているので、各ファイルのコメントを消していきましょう。コメントを消すと特になにも起こらない箇所もありますが、errorが起きる箇所もあります。

僕の場合は、コメントを消してerrorが起きたところは大抵`型がないパターン`だったのでとりあえず`any`をつけました。

元々のファイルの数が多いと、結構errorを潰していくのが面倒です...w

全てのerrorを消したら完了です！！
お疲れ様でした‼️

## 参考
[ts-migrate(公式)](https://github.com/airbnb/ts-migrate)
[ts-migrate: A Tool for Migrating to TypeScript at Scale](https://medium.com/airbnb-engineering/ts-migrate-a-tool-for-migrating-to-typescript-at-scale-cd23bfeb5cc)
[JSからTSへの移行ツール、ts-migrateを試してみた](https://qiita.com/Sotq_17/items/56403d3b8137affc1d10)
[Introduce TypeScript to react(js) project with ts-migrate😎](https://dev.to/kojikanao/introduce-typescript-to-react-js-project-with-ts-migrate-190h)