typescript-eslintの最新オプションno-unsafe-*を使って、TypeScriptの型リファクタリングを簡単に行った話

はじめに

OHEYAGOの開発の田渕です。

先日eslintを最大限活用してTypeScriptの型安全を少しずつ高める方法という記事を書きました。

さらに加えて、つい最近(約2週間前)、3/8にリリースされたtypescript-eslintの新機能を活用して更にリファクタリングすることができたので、紹介します。

現状とゴール

【現状】

explicit anyは残っておらず、殆どの箇所にtype annotationはされているが、implicit anyは残っている。

【ゴール】

tsconfig.json"strict": trueを設定し、コンパイラレベルでimplicit anyを防ぐ。

課題

パッと見ではimplicit anyは見つけられないが、compilerOptionで設定して確認すると10箇所程度残っている。
また、implicit anyを防ぐ仕組みがないので、今後の増加を抑えることも難しい。

影響範囲が散らばっており、一度のPRで全てのimplicit anyを潰すのは難しい。

typescript-eslintの新機能

3/8のtypescript-eslintのリリースにno-unsafe-call, no-unsafe-member-access, no-unsafe-returnの3つのルールが追加されました。これらのruleを使うと、implicit anyを少しずつ減らしていくことができます。

各ルールの説明をします

  • no-unsafe-call
    any型に対する関数呼び出し(anyVal()など)を禁止します。

  • no-unsafe-member-access
    any型に対するメンバ呼び出し(anyVal.hogeanyVal['hoge']など)を禁止します。

  • no-unsafe-return
    anyany[]が引数の返り値になることを禁止します。

いずれもimplicit anyがあった場合に検出します。
(厳密には、no-unsafe-returnについては、explicit-function-return-typeとno-explicit-anyが設定されていれば必要なさそうです)

'@typescript-eslint/no-unsafe-call': 1,
'@typescript-eslint/no-unsafe-member-access': 1,
'@typescript-eslint/no-unsafe-return' : 1,

上記のように全てwarnに設定すると、コンパイルやCIは通るけれど、implicit anyがある場合に警告が出てくれます。
このように設定してしまって、気づいたタイミングで徐々にimplicit anyを減らしていきましょう!

no-unsafe-*の警告がなくなったら

OHEYAGOの場合だと、その時点でtsconfigにno-implicit-any: trueを追加してコンパイルが通るようになっていました。
そうでなくても、implicit anyはかなり少なくなっていると思われるので、最後に少し頑張ってno-implicit-any: trueを設定してしまいましょう!
(ここまでやれば、すぐにstrict: trueにもしてしまえると思います)

これで、さらに型安全なコードベースができあがりました!!嬉しい!!!!

おわりに

TypeScriptのエコシステム周辺は進歩が著しく、追っていくのは大変です。
ですが、ちゃんと追っていけたこともあり、便利な機能をいち早く活用でき、プロダクトの保守性をまた一段と向上させることができました。

また何か共有できることがあったら、ブログの記事を書いていきたいと思います。