型ガード関数 (type guard function)
型ガードを使用することによってif
のブロックで特定の型に絞りこむことができます。
TypeScriptに元々用意されている型ガードとしてはtypeof
やinstanceof
がありますが、これ以外にもユーザーが独自に型ガードを定義することができます。
ユーザー定義の型ガード関数
ユーザー定義の型ガード関数を作るためにはType predicateを使用します。Type predicateの宣言は戻り値がboolean型の関数に対して適用でき、戻り値の型の部分を次のように書き替えます。
ts
functionisDuck (animal :Animal ):animal isDuck {returnanimal instanceofDuck ;}
ts
functionisDuck (animal :Animal ):animal isDuck {returnanimal instanceofDuck ;}
animal is Duck
の部分がType predicateです。これで関数isDuck()
がtrue
を返す時のif
のブロックの中ではanimal
はDuck
型として解釈されるようになります。
ts
// ここではquacks()は存在しないProperty 'quacks' does not exist on type 'Animal'.2339Property 'quacks' does not exist on type 'Animal'.animal .(); quacks if (isDuck (animal )) {animal .quacks ();// ...}
ts
// ここではquacks()は存在しないProperty 'quacks' does not exist on type 'Animal'.2339Property 'quacks' does not exist on type 'Animal'.animal .(); quacks if (isDuck (animal )) {animal .quacks ();// ...}
しかしながら、これはあくまでもその型であるとTypeScriptに解釈させるだけなので、JavaScriptとして正しいということは断言できません。
ts
functionisUndefined (value : unknown):value is undefined {return typeofvalue === "number";}
ts
functionisUndefined (value : unknown):value is undefined {return typeofvalue === "number";}
上記関数isUndefined()
は明らかに誤っていますが、この誤りに対してTypeScriptは何も警告を出しません。
関連情報
📄️ 制御フロー分析と型ガードによる型の絞り込み
TypeScriptは制御フローと型ガードにより、処理の流れに応じて変数の型を絞り込むことができます。