はじめに
はじめまして、新1年目エンジニアの細川です。業務で初めてTypeScriptを触って3か月くらいが経ちました。業務を進める中でいろいろ気になった点とかを備忘録としてまとめていきたいと思います。手始めとして、TypeScriptでよく用いられる型ガードについてまとめていこうと思います。基本の型ガードについて触れた後に、object
の型ガードについても触れていきますので、よろしくお願いします。
型ガードとは?
まず、型ガードとは何かについてです。型ガードとは型の絞り込みを行うコードです。型ガードを用いることで、明示的に型を指定しなくても型が特定されるようになります。わかりやすく言えば、型判別器のようなものです
typeof
を使った型ガード
まずは、typeof
演算子を使った型ガードについてです。typeof
演算子についてはこちらを参照してみてください。typeof
演算子の型ガードは主にユニオン型(例:string | number
)の値に対して型チェックを行いたいときに使うようです。以下にstring
型とnumber
型を判別するソースコードを示します。以下のコードではmonth
が与えられた時点ではstring
でもnumber
でもある可能性があるのですが、if
文によってstring
型に限定されるため、String
のメソッドであるpadStart()
が利用できます。
instanceof
を使った型ガード
続いて、instanceof
演算子を使った型ガードについてです。instanceof
演算子についてはこちらを参照してみてください。instanceof
演算子を用いることで、上と同じように、date
はDate
型に絞り込まれるため、Date
のメソッドであるgetMonth()
を利用できます。
任意のobject
の型ガード
続いて、任意のobject
の型ガードについてです。object
の場合はtypeof
やinstanceof
を使えない(object
の形式が変わっても返ってくる結果が同じ)ため、別の方法を用いて型の判定を行います。object
の型判定の場合はinを利用するみたいです。
in
を使った型ガード
in
演算子を使った型ガードについて説明します。in
演算子についてはこちらを参照してみてください。以下のソースコードのようにin
を使ってHuman
型かそうでないかを判定することができます。mammal
は与えられた時点ではHuman
型かDog
型かわかりませんが、talk
というプロパティがmammal
に含まれていればHuman
型、含まれていなければDog
型であるため、型を確定することができます。型が確定されれば、それぞれのメソッドを利用することができます。
is
について
今まで型ガードはすべてif
文の条件式内でのみ書いてきましたが、条件分岐が長くなったりすると、関数として切り分けたくなることもあると思います。その場合、is
演算子を用いることで、関数として記述することができます。is
演算子についてはこちらを参照してみてください。is
の効果としては、関数として条件を切り出しても、正しく型付けをしてくれるというものです。以下に図を示します。
説明を聞くだけではよくわからないと思うので、ソースコードでも見てみましょう。以下にまず、そのまま、切り出した場合を考えてみます。この場合、isHuman
の返り値はただのboolean
です。こう記述してしまうと、say
の中でmammal
はHuman | Dog
型のままで型が確定しないので、エラーになってしまいます。
このように、型ガードを関数として切り分けた場合には、is
演算子を使う必要があります。使い方は以下の通りで、isHuman
の返り値の型をmammal is Human
というように指定します。こうすることで、isHuman
の結果がtrue
になるならHuman
型、false
になるならDog
型に型付けをしてくれます。
応用編
object
の型ガードについてはin
を使う以外にすべてのプロパティをチェックするという方法もあります。以下のような型があるとします。
Human型かどうかを判別したい場合、以下のように各プロパティがすべてチェックできた場合にis Human
を返すようにすることで、判別することができます。実際に使う場合な度はundefined
やnull
のチェックも必要になるかと思います。
まとめ
業務で使う場合にはtypeofやinstanceof単体で使うよりも”応用編”のように組み合わせて使うことが多いかと思います。is
を使った型ガード関数は非常に便利ですが、条件にさえ合っていればまったく違う型でもその型になってしまうという問題がある点には注意してください。型ガードは特にしっかり確認して作った方がいいですね。