AIと人間のために、より正確な型を与えよう: 実装より広く宣言された戻り値型を捉える TypeScript ESLint カスタムルール
(github.com/minseong0324)TypeScript のコードベースを見ていると、
関数の実装はより狭い値を返しているのに、戻り値型はより広いまま残っているケースをよく目にします。
たとえば、次のようなコードです。
type Status = "idle" | "loading" | "error";
function getStatus(isLoading: boolean): Status {
if (isLoading) return "loading";
return "idle";
}
型宣言には error まで含まれていますが、実際の実装が返すのは idle と loading だけです。
このようなコードは TypeScript の観点では有効ですが、
リファクタリング後に使われなくなった戻り値型のメンバーが残ったままになったり、
実装より広い戻り値型の明示がそのまま維持されたりする問題につながることがあります。
実際には、こうしたケースは
•リファクタリング後に残った union メンバー
•実装とずれた手動の型指定
•AI が生成したやや緩い型アノテーション
といった状況でよく発生すると感じました。
そこで、
実装より広く宣言された戻り値型を検出する TypeScript ESLint カスタムルール を作ってみました。
https://github.com/minseong0324/eslint-plugin-no-misleading-return-type
たとえば、次のようなケースを対象にしています。
•union 型の一部メンバーがもはや返されていない
•string だが、実際の実装はより狭い literal union しか返さない
•Record<string, string> だが、実際の実装は特定の key を持つ as const オブジェクトを返す
•など
意図は「戻り値型を書かないようにしよう」ということではなく、
明示された戻り値型が実装と本当に一致しているかを改めて見直すためのガードレールを置くことです。
まだサポートしていない複雑なケースもあり、改善すべき点も残っていますが、
AI 時代にコード生成の速度が上がるほど、このような型ドリフトを自動で捉える仕組みがより必要になると感じて作ってみました。
フィードバック歓迎です。
1件のコメント
特に気になるのは、どこまでを意図された広い戻り値の型とみなし、どこからを実装と食い違った戻り値の型とみなすべきか、という点です。