typescriptのタイプガード


型を絞り込んでアクセスしたい時や、型によって処理を分けたい時などに使用されるType Guardについてです。

typeof

  const getData = (data: string | number): void => {
    if (data.length > 0) { //string | number
      console.log("string型:" + data); //string
    } else {
      console.log("number型:" + data); //number
    }
  };

getData関数の引数で入ってくるdataはstring型もしくはnumber型です。

if(data.length>0){}

この部分でstring型に絞りたいところですが、ts側からnumber型の可能性もあるよねっと言われてしまいます。
if文の中で使われているdataの型はまだnumber | stringの状態だからです。

上記のメソッドをtypeofによるタイプガードを利用して実装してみます。

  const getData = (data: string | number): void => {
    if (typeof data === "string") { //string
      console.log("string型:" + data); //string
    } else { 
      console.log("number型:" + data); //number 
    }
  };
if(typeof data = "string"){}

このif文でdataはstring型であると定義しているので、else文のdataは残りのnumber型だよねと推論してくれます。

ユーザー定義型のtypeGuard : parameterName is Type

 type Fish = { swim: () => void };
 type Bird = { fly: () => void };
const isFish = (pet: Fish | Bird): pet is Fish => {
  return (pet as Fish).swim !== undefined;
}

parameterName is Type
parameterName が typeであればtrueを返し、そうでなければfalseを返します。
 
ただ注意しておきたいのが、以下のような関数の場合です。

  const checkType = (value: string | number): value is string => {
    return typeof value === "string";
  };
  const checkType = (value: string | number): value is string => {
    return typeof value === "number";
  };

checkType関数の場合value is stringreturnのtypeofで指定している型が矛盾しています。
ここの型が矛盾していてもtsではエラーが出ずにそのまま通ってしまいます。
value is stringreturnのtypeofで使用する型は、矛盾がないようにしないと予定していない処理が走ってしまいそうです。