メインコンテンツまでスキップ

型ガード関数 (type guard function)

型ガードを使用することによってifのブロックで特定の型に絞りこむことができます。
TypeScriptに元々用意されている型ガードとしてはtypeofinstanceofがありますが、これ以外にもユーザーが独自に型ガードを定義することができます。

ユーザー定義の型ガード関数

ユーザー定義の型ガード関数を作るためにはType predicateを使用します。Type predicateの宣言は戻り値がboolean型の関数に対して適用でき、戻り値の型の部分を次のように書き替えます。

ts
function isDuck(animal: Animal): animal is Duck {
return animal instanceof Duck;
}
ts
function isDuck(animal: Animal): animal is Duck {
return animal instanceof Duck;
}

animal is Duck の部分がType predicateです。これで関数isDuck()trueを返す時のifのブロックの中ではanimalDuck型として解釈されるようになります。

ts
// ここではquacks()は存在しない
animal.quacks();
Property 'quacks' does not exist on type 'Animal'.2339Property 'quacks' does not exist on type 'Animal'.
 
if (isDuck(animal)) {
animal.quacks();
// ...
}
ts
// ここではquacks()は存在しない
animal.quacks();
Property 'quacks' does not exist on type 'Animal'.2339Property 'quacks' does not exist on type 'Animal'.
 
if (isDuck(animal)) {
animal.quacks();
// ...
}

しかしながら、これはあくまでもその型であるとTypeScriptに解釈させるだけなので、JavaScriptとして正しいということは断言できません。

ts
function isUndefined(value: unknown): value is undefined {
return typeof value === "number";
}
ts
function isUndefined(value: unknown): value is undefined {
return typeof value === "number";
}

上記関数isUndefined()は明らかに誤っていますが、この誤りに対してTypeScriptは何も警告を出しません。

関連情報

📄️ 制御フロー分析と型ガードによる型の絞り込み

TypeScriptは制御フローと型ガードにより、処理の流れに応じて変数の型を絞り込むことができます。