[TypeScript] TypeGuard とは


TypeGuardってなに

条件ブロック内でオブジェクトの型を制限すること。

例えば、ある関数の中で if (typeof hoge === "undefined") return
書いたとします。
するとその関数内では以後、hogeundefinedである事はないですよね。
こうやってオブジェクトが複数の型を持つ場合に型を制限することを指します。

どういう時に使うのか?

どんな型のデータでも引数に受け取りたい時(例えばJSONデータやオブジェクト)。

関数の引数でanyを使ってしまっているよ...lintが怒っている(anyは使わないのがベスト)

そんなときはTypeGuardをして余計なものを排除しましょう。

実例

今回はURLに乗っているクエリパラメータの一部分の数字を取得して変数に格納したいケースですが、
背景は気にしないで結構です。雰囲気作りが大事だと思っているので背景をつけました(なるほだない)

sample.ts

const hogeRound = null;

// まずURLの?で始まる検索クエリ部分を参照する
const { search } = location;

// 取得したクエリパラメータから1文字目を除いてオブジェクトにパースする
// この時点でqueriesはany型
const queries.roundId = qs.parse(search.substr(1));

function typeGuard (queries.roundId) {
  //求めてるid以外のクエリが入ってくる可能性を考慮してる
  if (queries.roundId) {
    // queries.roundIdという文字列をNumber型かつ数字に変換してroundIdに格納
    const roundId = Number.parseInt(queries.roundId, 10);
    // クエリvalueに数字以外が渡ってくることを防ぐ(型絞り込みその1)
    if (!Number.isNaN(roundId)) {
      // オブジェクトにパースする
      const queryId = JSON.parse(String(roundId));

      // number型でさらに絞り込む(型絞り込みその2)
      if (typeof queryId === "number") {
        // hogeRound.idはほぼnumber型
        hogeRound.id = queryId;

        hogeRound.id.type === "number"
      }
    }
  }
}

location.searchについてはこちら
qs.parseについてはこちら
substr()についてはこちら
Number.parseInt()についてはこちら
JSON.parse()についてはこちら
typeofについてはこちら

こうして入ってくるデータの型を制限することでhogeRound.idはほぼ間違いなくnumber型しか入らない形になりました(厳密には違いますが)。

このようにデータの型が確定された時に true を返す関数の事

おしまい。