TypeScriptでHooksやService(APIとの連携や型変換、返り値のハンドリングなど)、UIコンポーネントの汎用化を書いていると、コードがどんどん読みづらくなったり理解しづらくなったりするのではないでしょうか。私はします。
しかし、具体的にどういう読みづらさなのかは、行数が多いとか分岐やPromiseなどによるネストあたり以外にパッと答えづらいと思います。
このようなときは「複雑性(Complexity)」を算出してしまいましょう!
さらに複雑化してしまったコードをリファクタリングするにあたり、ChatGPTを使ってしまおうという話です。
Complexityの設定
Complexityについての説明は以下のQiitaがとても参考になります。
※上記記事中に書かれているTypeScript向けの cyclomatic-complexity
は、2020年にTSLintが非推奨となったため個人的にも推奨はしません。
これに加えて sonarjs
が提供しているプラグインも追加すると尚良しです(重複して検出されてしまう部分はありますが、それはそれで)
以下手順です。
eslint-plugin-sonarjsのインストール
以下はnpmですが、yarnでもpnpmで読み替えてください。
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier prettier eslint-plugin-sonarjs
ESLintの設定
以下は.jsにしてますが、.jsonの場合はそのフォーマットに従ってください。
また、 ESLint8 が前提です。自身のプロジェクトから掻い摘んで最小の構成にしているので、動かなかったらごめんなさい……。
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true,
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:sonarjs/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"import",
"sonarjs",
],
"rules": {
"complexity": ["error", 10],
},
};
complexityの詳細な説明:
これで完了です。
実際にlinterを実行したときの例
こんな感じで出力されます。
/Users/bon/work/test/aaa.ts
3:3 warning Replace this if-then-else flow by a single return statement sonarjs/prefer-single-boolean-return
/Users/bon/work/test/bbb.ts
5:8 warning Function 'checkValid' has a complexity of 17. Maximum allowed is 10 complexity
1行目が sonarjs/prefer-single-boolean-return
で、 2行目が complexity
のLinterの警告です。
ChatGPTに仕事をさせる
ここからはAIの出番です。
LLMが出てくるまでは、人が頑張ってリファクタリングしていたと思うのですが、ある程度であればChatGPTに雑に聞くだけでなんとかなります。
プロンプトの例は以下のような感じです。
これから入力するコードはESLintによってComplexityが10以上と判断された複雑性のあるコードです。
このコードをリファクタリングして、Complexityが9以下となるように修正してください。修正してもらったコードを再度Linterを実行して検証します。
なお、その際に改めてComplexityが10を超えてしまった場合は再度コードを入力するのでその都度リファクタリングをしてください。
発生している警告は以下です。
(ESLintの警告文を貼る)
対象のコードは以下です。
(コードを貼る)
これだけでなんかいい感じにComplexityが減っていきます。
あとは変数名やコメントなどを適宜人間が加筆修正するだけです。生産性バク上がりですね。ぜひお試しください。
ちなみに所感ですが、10程度ならギリギリコードリーディング可能な印象を受けます。13あたりになるとPropsの指定でどう出し分けができるのかわからなかったり、分岐が多くて組み合わせによる条件網羅が把握しづらかったりします。総合するとComplexityを11くらいにするとちょうどよいかもしれません。
なお、例で出ている 17 という数値は使ってみても出し分けがどうなるかわからん闇鍋メソッドです。(所感)