Next.js + サーバーサイドTypeScript + 関数フレーバーでクリーンなアプリを作ったので実装意図とか書く Advent Calendar 2022
の7日目。株式会社mofmofに生息しているshwldです。
前日は関数の合成について書きました。
Either型
一般的なアプリケーションは、処理の途中でこれ以上処理を進められなくなることがあります。
不正な入力データであったり、外部のシステムやデータベース、その他無数の要因で同じ処理でもエラーになってしまったり、エラーの原因は様々。
昨日書いた関数合成の中でそういったエラーが起きたらどうしよう。
pipe(
input,
validation,
build,
save,
sendMail,
)
こんな風に、入力をバリデーションして、データを整形してDBに保存して、メール送信するみたいな処理を書いたとき、
バリデーションが失敗したらそれ以降は実行してもらいたくない。
こういうときにはEitherを利用すると良い。
Eitherは正常な結果と、そうでない結果の型を表現できる。
慣習として left
が正しくないデータ、 right
が正しいデータとしてどちらかの場合であることを表現できる。
- これを使うことでvalidationの結果、不正なデータだった場合にはleftを返すようにする
- buildやsaveはrightだけを受け取って処理する、leftだったら何もせずに次に送る
というように失敗データを無視して後続処理に受け渡すことができる
また、fp-tsには、新たに生まれた例外パターンを leftにunionとして加える、Either#chainW がある。
例
validation() // 失敗ならleftで`InvalidError`を返す
build() // Either rightのときだけ処理する
save() // Either rightのときだけ処理する。失敗なら`DBError`または`InvalidError`をleftで返す
mail() // Either rightのときだけ処理する。失敗なら`MailSendError`または`DBError`または`InvalidError`をleftで返す
handleError() // Either leftのときだけ処理する。`MailSendError`または`DBError`または`InvalidError`を受け取る
これを使えば、順番に実行していく中で発生するエラーのパターンをすべてunionとしてleftで保持しつつ最後にエラー処理をするということが可能で、良い(語彙力)
最後にエラー処理する際に、エラーを ts-pattern などを使ってもれなく処理すれば、どのエラーを処理漏れているかを型でチェックできたりと旨味が大きい。
デメリットとしては、入力にEitherを取ることが増えてちょっとめんどくさいなとか感じることだろうか。
次回予告
明日はTaskEitherについて書きます