📝

【TypeScript】ユーザー定義の型ガード関数を使った

2024/03/11に公開

はじめに

こんにちは、daikiです!
普段はフロントエンドエンジニアとして業務をしており、
主にTypeScriptやNext.jsなどの技術を触っています。
開発の状況によってはバックエンドも行っており、使用言語はGoです。

今回は業務で一覧画面を作成したのですが、そこでユーザー定義の型ガード関数を学んだので、記録に残しておきたいと思い、記事にしました。

使用技術

  • React v18
  • TypeScript v5
  • Next.js v14 (App Router)

使用前

実装した一覧画面には検索機能があり、検索ボタンを押下したらURLのクエリパラメーターを追加して、その変更を検知し、APIを実行する流れで一覧画面を作成していました。
その際、初期表示時に不正なクエリパラメータがある場合は検索していない状態の一覧画面にリダイレクトをさせたかったので、以下のようにuseEffect内で不正かどうかの判定をしていました。

// 型定義
type TestEnum = (typeof TestEnum)[keyof typeof TestEnum];

const TestEnum = {
  testA: "testA",
  testB: "testB",
} as const;
  // 初期表示時にURLパラメータのtypeが不正な場合はリダイレクトする
  useEffect(() => {
    const testType = searchParams.get("type") || undefined;
    if (testType === undefined) return;
    if (testType === TestEnum.testA) {
      // 処理...
      return;
    }
    if (testType === TestEnum.testB) {
      // 処理...
      return;
    }
    router.push("/list"); //
  }, [router, searchParams]);

使用後

レビュー指摘をいただき、以下のようにユーザー定義の型ガードを使って修正しました。

// 関数を作成
const isValidType = (type: string): type is TestEnum => {
  const validTypes: string[] = Object.values(TestEnum);
  return validTypes.includes(type);
};

// コンポーネント側
if (typeof testType === 'string' && !isValidType(testType)) {
  redirect("/list");
}

このようにユーザー定義の型ガードを使用することによって、useEffectを使用せずに実装することができました。
また、これをpage.tsxに実装していたので、使用前の場合は"use client"を指定しなければなりませんでした。しかし、使用後であれば"use client"を指定する必要がないため、クライアントモジュールグラフを少しでも少なくすることができました!

まとめ

今回はユーザー定義の型ガード関数を実装したため、その記録として記事にまとめました。
TypeScriptにはまだまだ知らないことが多いので、また学びがあった時は引き出しを増やすためにまとめていこうと思いました。

参考記事

https://typescriptbook.jp/reference/functions/type-guard-functions

Discussion