if文が深くなると、コードは読みにくくなります。
そんなときに役立つのが、早期returnとガード節です。
一言でいうと
ガード節は、先に例外条件を返して、本筋の処理を読みやすくする書き方です。
成功パターンを深いif文の中に閉じ込めず、まっすぐ読めるようにします。
ネストが深い例
function getDiscount(user: User | null) {
if (user) {
if (user.isActive) {
if (user.purchaseCount >= 10) {
return 0.1;
}
return 0.03;
}
return 0;
}
return 0;
}
条件を追うために、右へ右へ読まなければいけません。
ガード節を使った例
function getDiscount(user: User | null) {
if (!user) return 0;
if (!user.isActive) return 0;
if (user.purchaseCount >= 10) {
return 0.1;
}
return 0.03;
}
先に対象外のケースを返すことで、本筋が読みやすくなりました。
ガード節が向いている場面
| 場面 | 例 |
|---|---|
| 入力がない | if (!user) return |
| 権限がない | if (!canEdit) return |
| 対象外の状態 | if (status !== "active") return |
| エラーを早く出す | if (!email.includes("@")) throw |
「この条件を満たさないなら、この先の処理をしてはいけない」という場合に向いています。
ガード節のメリット
- ネストが浅くなる
- 本筋の処理が見えやすい
- 異常系と正常系を分けやすい
- 条件の追加がしやすい
特に、入力チェックや権限チェックでは効果が大きいです。
使いすぎに注意
早期returnが多すぎると、逆に流れが追いにくくなることもあります。
function calculate(input: Input) {
if (!input.a) return 0;
if (!input.b) return 1;
if (!input.c) return 2;
if (!input.d) return 3;
return 4;
}
条件が多い場合は、状態を整理したり、別関数に分けたりするほうがよい場合があります。
まとめ
早期returnとガード節は、ネストを浅くし、本筋の処理を読みやすくする書き方です。
先に対象外の条件を返し、正常な流れをまっすぐ読めるようにしましょう。
参考リソース
- Refactoring: Replace Nested Conditional with Guard Clauses
- Martin Fowler: Refactoring
- Cognitive Complexity