TypeScript Option 型の有用性について考えてみた

以前Optoin型について書きました。こちら

今回はOption型をどのような時に使うのか、なぜ使うのかについて自分なりに考えてみました。

とあるシステムで、商品番号を取得して返す関数があるとします。

この関数は商品番号を取得できた場合はその番号を、もし取得に失敗した場合は0を返すとします。

const getProductId = (): number => {
  // 取得処理
}

さて、この関数を使う側で気を付けることはなんでしょうか。

それは以下です。

  • 商品番号の取得に失敗することがある
  • 失敗した時は0が返る

この二点を開発者が認識していないといけません。

つまり、getProductId の結果が0かそれ以外かをチェックして、それぞれに対応した分岐を書く必要があります。

しかし、開発者は人間なので、この二つを忘れる可能性があります。

忘れた場合はバグになります。

それでは、この二点を絶対に忘れないようにシステム的にすることはできないでしょうか。

そこでOption型を使用します。

type Some<T> = {
  hasSome: true
  value: T
}
type None = {
  hasSome: false
}
type Option<T> = Some<T> | None

const getProductId = (): Option<number> => {
  // 取得処理
}

Option 型を使うことで、この関数を利用する側では、必ず成功したか失敗したかをチェックする必要があります。

そうしないと、商品番号(value)を取得することができません。(成功か失敗かをチェックしないでvalueを取得しようとするとコンパイルエラーになる)

ここで、はじめの例に戻ってみます。

もし、失敗した場合にnullを返すようにしてあげれば、Option型は必要ないのでは?と感じます。

const getProductId = (): number | null => {
  // 取得処理
}

たしかに、これであれば成功か失敗かをチェックしないと型が確定しないので、Option型を使ったときと同じ効果が得られそうです。

ただ、Option型を使った方が、Option型から値を取得する処理を汎用的にでき、かつ、成功と失敗の処理を羅列できると思うので、利用する側の処理が明確で簡潔になるメリットがあると思っています。

この点については、また改めて考えてみたいと思います。