TypeScriptのあれこれ①型ガードについて

はじめに

はじめまして、新1年目エンジニアの細川です。業務で初めてTypeScriptを触って3か月くらいが経ちました。業務を進める中でいろいろ気になった点とかを備忘録としてまとめていきたいと思います。手始めとして、TypeScriptでよく用いられる型ガードについてまとめていこうと思います。基本の型ガードについて触れた後に、objectの型ガードについても触れていきますので、よろしくお願いします。

型ガードとは?

まず、型ガードとは何かについてです。型ガードとは型の絞り込みを行うコードです。型ガードを用いることで、明示的に型を指定しなくても型が特定されるようになります。わかりやすく言えば、型判別器のようなものです

typeofを使った型ガード

まずは、typeof演算子を使った型ガードについてです。typeof演算子についてはこちらを参照してみてください。typeof演算子の型ガードは主にユニオン型(例:string | number)の値に対して型チェックを行いたいときに使うようです。以下にstring型とnumber型を判別するソースコードを示します。以下のコードではmonthが与えられた時点ではstringでもnumberでもある可能性があるのですが、if文によってstring型に限定されるため、StringのメソッドであるpadStart()が利用できます。

instanceofを使った型ガード

続いて、instanceof演算子を使った型ガードについてです。instanceof演算子についてはこちらを参照してみてください。instanceof演算子を用いることで、上と同じように、dateDate型に絞り込まれるため、DateのメソッドであるgetMonth()を利用できます。

任意のobjectの型ガード

続いて、任意のobjectの型ガードについてです。objectの場合はtypeofinstanceofを使えない(objectの形式が変わっても返ってくる結果が同じ)ため、別の方法を用いて型の判定を行います。objectの型判定の場合はinを利用するみたいです。

inを使った型ガード

in演算子を使った型ガードについて説明します。in演算子についてはこちらを参照してみてください。以下のソースコードのようにinを使ってHuman型かそうでないかを判定することができます。mammalは与えられた時点ではHuman型かDog型かわかりませんが、talkというプロパティがmammalに含まれていればHuman型、含まれていなければDog型であるため、型を確定することができます。型が確定されれば、それぞれのメソッドを利用することができます。

isについて

今まで型ガードはすべてif文の条件式内でのみ書いてきましたが、条件分岐が長くなったりすると、関数として切り分けたくなることもあると思います。その場合、is演算子を用いることで、関数として記述することができます。is演算子についてはこちらを参照してみてください。isの効果としては、関数として条件を切り出しても、正しく型付けをしてくれるというものです。以下に図を示します。

説明を聞くだけではよくわからないと思うので、ソースコードでも見てみましょう。以下にまず、そのまま、切り出した場合を考えてみます。この場合、isHumanの返り値はただのbooleanです。こう記述してしまうと、sayの中でmammalHuman | Dog型のままで型が確定しないので、エラーになってしまいます。

このように、型ガードを関数として切り分けた場合には、is演算子を使う必要があります。使い方は以下の通りで、isHumanの返り値の型をmammal is Humanというように指定します。こうすることで、isHumanの結果がtrueになるならHuman型、falseになるならDog型に型付けをしてくれます。

応用編

objectの型ガードについてはinを使う以外にすべてのプロパティをチェックするという方法もあります。以下のような型があるとします。

Human型かどうかを判別したい場合、以下のように各プロパティがすべてチェックできた場合にis Humanを返すようにすることで、判別することができます。実際に使う場合な度はundefinednullのチェックも必要になるかと思います。

まとめ

業務で使う場合にはtypeofやinstanceof単体で使うよりも”応用編”のように組み合わせて使うことが多いかと思います。isを使った型ガード関数は非常に便利ですが、条件にさえ合っていればまったく違う型でもその型になってしまうという問題がある点には注意してください。型ガードは特にしっかり確認して作った方がいいですね。

参考

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です