TypeScriptのLint
JavaScriptもTypeScriptも混じっているプロジェクトで、Lintのルールをなるべく共通化して運用したいというモチベーションがある。
JavaScriptのLinterはESLintを使いたい。TypeScriptのLinterはTSLintがデファクトだが、TSLintはESLintと比べて実装されているルールがだいぶ少なかったり、同じルールでも名前が違ったりする。
解決するアプローチは以下の二つがある。
typescript-eslint-parser
https://github.com/eslint/typescript-eslint-parser
ESLintのパーサーにTypeScriptを使うことでTypeScriptのLintをESLintで行う。JSもTSも同じ設定でいけるので最高便利。なんだけどREADMEに
Important: This parser is not fully compatible with all ESLint rules and plugins. Some rules will improperly mark source code as failing or not find problems where it should.
とあるように対応が不完全なところもあるのが難点。
現状で一番致命的なのは未定義の変数を検出するno-undef
を有効にしていると、以下の箇所でエラーになるというバグもの。
class Foo { a: string; //=> error 'a' is not defined no-undef constructor() { this.a = "a"; } }
ワークアラウンドな対応として、TypeScriptのときだけno-undef
をoff
にすればいい。未定義な変数はTypeScriptのコンパイラで検出できるし。
overrides: files: ['**/*.ts', '**/*.tsx'] parser: typescript-eslint-parser rules: no-undef: off
こういう感じで。
また、TypeScript specificなルールを使うには以下のようなプラグインがあるが、TSLintには及ばないので型情報が必要なLintはある程度諦めが必要になる。 https://github.com/nzakas/eslint-plugin-typescript
tslint-eslint-rules
https://github.com/buzinas/tslint-eslint-rules
もう一つがTSLintをESLintに寄せるためのモジュール。ESLintにあってTSLintにないルールを補完する*1。方向性としてはよいんだけど、現時点では対応していないルールもかなり多い。あと、TSLint本体のルールがESLintのルールと名前が違う問題は解決されない。
どっちを使うか
状況にもよると思うけどtypescript-eslint-parserを使ってESLintに寄せるようにした。ESLintとTSLintを併用しないで済むし、ESLintの豊富なルールも使える(使うかどうかは置いといて)ので、多少バグっていることを差し引いてもこちらのアプローチのほうが運用が楽そうだった。
*1:なんでTSLint本体にコントリビュートしないのかよくわからない