脱TSLintして、ESLint TypeScript Plugin に移行する

## なぜ脱 TSLint するのか
いままで TypeScript の Linter として **TSLint** を使っていました。
ですが、TSLint は開発コミュニティが活発とはいえないことが以前から指摘されていました。

- [TSLint is dead \- Klaus Meinhardt \- Medium](https://medium.com/@klaus.meinhardt1/tslint-is-dead-31f55c8fce1f)

そんな中で、TSLint 開発チームは ESLint のプラグインとして TSLint の機能を統合していく **typescript-eslint プロジェクトを開始し、TSLint は 2019年中に非推奨となる予定である** ことが発表されました。

- [Roadmap: TSLint \-> ESLint · Issue \#4534 · palantir/tslint](https://github.com/palantir/tslint/issues/4534)
- [typescript\-eslint/typescript\-eslint: Monorepo for all the tooling which enables ESLint to support TypeScript](https://github.com/typescript-eslint/typescript-eslint)

また、Microsoft の TypeScript 自体のリポジトリも以前は TSLint を使っていたのですが、2019年9月頃に ESLint に移行しました。

- [Migrate the repo to ESLint · Issue \#30553 · microsoft/TypeScript](https://github.com/microsoft/TypeScript/issues/30553)
- [Migrate the repo to ESLint by a\-tarasyuk · Pull Request \#31777 · microsoft/TypeScript](https://github.com/microsoft/TypeScript/pull/31777)

**ESLint** は JavaScript 開発における強力なエコシステムとしての地位をすでに確立しています。ESLint と TSLint の目的は同じであり、無理に差別化するのではなく共存を目指すべき、という判断は妥当だと思います。

- [ESLint \- Pluggable JavaScript linter](https://eslint.org/)

本稿では、実際に TSLint から ESLint へ移行する方法を示します。簡単です。

## 環境
- Windows 10 Pro 1809 Windows Subsystem for Linux (Bash on windows) Ubuntu 16.04.4 LTS
    - たぶんMacでも同じです
- TypeScript: 3.5.3
- ESLint: 6.0.1
- @typescript-eslint/eslint-plugin: 1.12.0



## 移行方法
まず TSLint を外します。おせわになりました。

```diff:package.json
-    "tslint": "^5.17.0",
-    "tslint-config-prettier": "^1.18.0", 
-    "tslint-plugin-prettier": "^1.3.0",
```

新しく`eslint`や`@typescript-eslint/eslint-plugin` 等、必要になるパッケージをインストールします。

```
$ npm install --save-dev eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier eslint-config-prettier eslint-plugin-prettier
```

TSLint の設定ファイルである`tslint.json` を削除します。
そして新たに`.eslintrc.json` を追加します。

TSLint と ESLint とで移行前後でルールの互換性が必要な場合は [typescript\-eslint/tslint\-to\-eslint\-config](https://github.com/typescript-eslint/tslint-to-eslint-config) を使ったりするとうまくいくかもしれません。
(参考: [tslint\-to\-eslint\-configでtslint\.jsonをeslintrcに変換する \- Qiita](https://qiita.com/shisama/items/b3d63142797b07cb554e) )


今回は思い切って ESLint の Recommended の設定にすべてを委ねます。`.eslintrc.json` 設定内容の例はこんな感じです。


```.eslintrc.json
{
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended",
    "prettier/@typescript-eslint"
  ],
  "plugins": [
    "@typescript-eslint"
  ],
  "env": { "node": true, "es6": true },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "rules": {
  }
}
```

必要に応じて npm scripts なども変更します。

```diff:package.json
  "scripts": {
-    "lint": "tslint src/index.ts",
+    "lint": "eslint src/index.ts",
-    "lint:fix": "tslint --fix src/index.ts"
+    "lint:fix": "eslint --fix src/index.ts" 
```

VSCode の拡張機能も使っていたら、[ESLintの拡張機能](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) に変更します。

```diff:.vscode/extensions.json
  "recommendations": [
-    "eg2.tslint"
+    "dbaeumer.vscode-eslint"
```

VSCode 以外のツールの拡張機能は以下に紹介されています。

- [Integrations \- ESLint \- Pluggable JavaScript linter](https://eslint.org/docs/user-guide/integrations)

これで準備は完了です。
`$ npm run lint` コマンドなり、VSCode の Probrems タブなりに指摘事項が出てくると思うので、修正していくだけです。

### 例

下記は`@typescript-eslint/no-unused-vars`ルールに引っ掛けてみた例です。ついでに ESLint と Prettier もエラーを出してくれているのが分かります。

```src/index.ts
var hoge = 1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/7576caec-517b-67db-bfdb-22bb4e4e3892.png)

```bash
$ head -n 1 src/index.ts  
var hoge = 1
$ npx eslint src/index.ts  

/path/to/src/index.ts 
  1:1   error    Unexpected var, use let or const instead   no-var
  1:5   warning  'hoge' is assigned a value but never used  @typescript-eslint/no-unused-vars
  1:13  error    Replace `⏎` with `;`                       prettier/prettier

✖ 3 problems (2 errors, 1 warning) 
  2 errors and 0 warnings potentially fixable with the `--fix` option.
```

もし修正できない内容があれば、TSLint と同様に Disabling comments を使えばエラーを止めることができます。

```diff
-// tslint:disable-next-line:no-var-requires
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const commander = require("commander");
```

簡単ですね。

実際に筆者が TSLint から ESLint への移行時に修正した内容は下記です。
[TypeScript ESLint fix · s2terminal/i\-read\-u@191d349](https://github.com/s2terminal/i-read-u/commit/191d349fc4a209ad99192e287b1384905d203060)

## 参考
- [@typescript\-eslint ことはじめ \- teppeis blog](https://teppeis.hatenablog.com/entry/2019/02/typescript-eslint)