TypeScript in演算子の型ガード

TypeScirptでは、条件文でin演算子を使った時にも型ガードとして利用できます。

型ガードとは、条件ブロック内でオブジェクトの型を制限できることです。

以下のコードをみてみます。

type Hoge = {
    hoge: string
}
type Foo = {
    foo: string
}

const myFunc = (data: Hoge | Foo) => {
    //この時点ではdataはHogeかFooのどちらかは分からない
    if('hoge' in data){
        //data: Hoge と推論される
        console.log(data.hoge)
        console.log(data.foo) //コンパイルエラー
    }else{
        //data: Foo と推論される
        console.log(data.foo)
        console.log(data.hoge) //コンパイルエラー
    }
}

HogeとFooという型があります。

それぞれ、hogeというプロパティとfooというプロパティを持っています。

myFunc の引数にはdataが渡されますが、dataはHogeかFooのどちらかの型になります。

myFuncにはif文がありますが、if文の前の時点ではdataはHoge型なのかFoo型なのか不明です。

そのため、if文よりまで console.log(data.hoge) のようにすると、Foo型にはhogeプロパティはありませんとコンパイルエラーになります。

しかし、ifの条件文のように in 演算子で、’hoge’プロパティの存在チェックをし結果がtrueだった場合は、dataはHoge型であると推論されます

そのため、console.log(data.hoge) はコンパイルエラーになりません。一方で、console.log(data.foo)はコンパイルエラーになります。

そして、else のブロック内では、dataはHogeではない型である = Foo型であると推論されるので console.log(data.foo) はコンパイルエラーになりません。

このようにTypeScriptでは、if文の条件でinを使うことで条件ブロックで型ガードを使用できます。