LoginSignup
38
22

More than 3 years have passed since last update.

TypeScriptでNullableと向き合う

Last updated at Posted at 2019-08-13

2019/11/11追記

TypeScript3.7からOptional Chainingが導入されました!
ここで記述されている?.演算子が使えるようになったため、以下の議論が比較的きれいにかけるようになりました。

TypeScript3.6までのNullable

たとえば、こんなコードがある。

JavaScript
document.getElementById('loader').style.display = 'none'

TypeScriptではJavaScriptで↑のように書けていたコードはそのまま書くと、

error TS2531: Object is possibly 'null'.

と怒られるため、↓のように書かなくてはならない。

TypeScript(compiled-with-strict)
const loader = document.getElementById('loader')
if (loader) {
  loader.style.display = 'none'
}

これはdocument.getElementById()の返す型がHTMLElement | nullであるため、
Nullチェックを行えという至極真っ当な主張である。

言ってしまえば、JavaScriptの方のコードは潜在的なバグあるということに気付かされる場面でもある。

しかし、みなさんにはどうでもいいかもしれないがこういったことでif文を書き、ネストが一つ深まるのが個人的には好きではない。

ではどうするか?

他の言語ではどうなの?

他の言語の場合、Null条件演算子(Safe Navigation Operator)というものがある。
Null条件演算子を使用した場合、nullが検出されて以降のメソッドやフィールドの評価を行わずにnullをその結果として返す。
たとえば、C#やSwiftだったら以下のように書けるはずだ。

Null条件演算子をサポートしている場合
document.getElementById("loader")?.style.display = "none"

確かに、↑のように書けることができれば、いけ好かないif文を書く必要がなくなる。
しかし、TypeScriptではこのような演算子はまだ存在しないようだ。

似たような文法は確かに存在していて、

TypeScript
document.getElementById('loader')!.style.display = 'none'

と書けることにはたしかに書ける。

調べるとx!演算子Non-null Assertion Operatorというものらしい。
xNon-nullNon-undefinedと断定できる場合に使用できる。

しかしこれではJavaScriptのコードと何ら変わりはない。
今回に関して言えば、いけ好かないif文を書いたほうが数億倍マシまである。
というのもNull条件演算子を見たあとにこれでは悲しすぎる。

ではどうする?

一時期、Null許容型Null安全型に関しての議論がよくされていた。
タイトルのNullableNull許容型に当たる。
document.getElementById()でいえばHTMLElement | nullをしてNull許容とここではしておく。

TypeScriptを使用する際に、私がよく使う便利なライブラリにfp-tsというライブラリがある。
これはTypeScriptに関数型プログラミングの考え方を導入するためのライブラリである。

幸いなことに、提供するものの中にはNull安全でおなじみのOptionがある。
毎度、TypeScriptを使用するときにこのライブラリも使うんだから、これ利用してどうにかきれいに書けないかと考えることにした。

とりあえず書いてみた。

TypeScript(Option導入後)
import { pipe } from 'fp-ts/lib/pipeable'
import { fromNullable, map } from 'fp-ts/lib/Option'

pipe(
  document.getElementById('loader'),
  fromNullable,
  map((loader) => { loader.style.display = 'none' })
)

律儀に改行しまくったため、長く見えるが、if文が消えたので良しとする。

やっていることとしてはNullable型からOption型へ変換し、document.getElementById('loader')nullではなかったらmapに渡した関数が適用されるといった感じになる。

この程度のことでOptionをわざわざ引っ張り出すのは大げさかもしれないが規模が大きくなるに比例して、Null安全の概念を導入することは有利に働くと思うのでこういったことで慣れておくのもいいだろう。

38
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
22