0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【実務で使える】TypeScript Utility Types まとめ

0
Posted at

はじめに

TypeScriptには標準で用意されている Utility Types があり、既存の型を変換して新しい型を作ることができます。

「存在は知ってるけど PartialPick くらいしか使ってない」という方も多いのではないでしょうか。実際、実務で使いどころを押さえておくとコードの見通しがかなり良くなります。

この記事では、よく使う Utility Types を 「どんな場面で使うと便利か」 という観点で整理しました。

本記事は @KaraBharat氏のツイート を参考に、実務での使い方を補足してまとめたものです。

ベースとなる型

以降の例ではすべてこの User 型を使います。

interface User {
  id: string;
  name: string;
  email?: string;
  role: "admin" | "editor" | "viewer";
}

email がオプショナルになっている点がポイントです。


Partial<T> — 更新リクエストに便利

const updateUser: Partial<User> = { email: "new@domain.com" };

すべてのプロパティをオプショナルにする型です。

使いどころ

  • PATCH API のリクエストボディ(変更したいフィールドだけ送る)
  • フォームの部分的なバリデーション
  • setState のようにオブジェクトの一部だけ更新する場面
function updateUser(id: string, data: Partial<User>) {
  // data には User のうち好きなフィールドだけ入っていればOK
}

Required<T> — オプショナルを許さない場面に

const completeUser: Required<User> = {
  id: "cgjhfgx676",
  name: "Adam",
  email: "adam@gmail.com",  // ← email も必須になる
  role: "admin",
};

すべてのプロパティを必須にする型です。Partial の逆ですね。

使いどころ

  • DB保存前のバリデーション後の型(「全フィールドが埋まっている」ことを型で保証)
  • フォーム送信時の最終チェック
  • テストデータの作成(フィールド漏れを防ぐ)

Readonly<T> — うっかり変更を防ぐ

const staticUser: Readonly<User> = {
  id: "cgjhfgx676",
  name: "Adam",
  role: "viewer",
};

// staticUser.role = "admin";  // ← コンパイルエラー!

すべてのプロパティを readonly にする型です。

使いどころ

  • API レスポンスをそのまま保持する変数(意図しない書き換え防止)
  • Redux の state や、React の props から受け取ったデータ
  • 設定値やマスターデータなど、変更されるべきでないオブジェクト

Pick<T, K> — 必要なプロパティだけ抜き出す

type UserSidebar = Pick<User, "name" | "role">;
// { name: string; role: "admin" | "editor" | "viewer" }

使いどころ

  • UIコンポーネントに渡す props の型を作るとき
  • 一覧画面で表示に必要なフィールドだけ抽出
  • GraphQLのフラグメントのような感覚で「この画面ではこれだけ必要」を明示
// サイドバーはユーザーの名前とロールだけ知っていればいい
const SidebarItem: React.FC<UserSidebar> = ({ name, role }) => { ... };

Omit<T, K> — 特定のプロパティを除外する

type NewUserRequest = Omit<User, "id">;
// { name: string; email?: string; role: "admin" | "editor" | "viewer" }

Pick の逆で、指定したキーを除いた型を作ります。

使いどころ

  • POST API のリクエスト型(id はサーバー側で自動生成するので送らない)
  • フォームの入力型(createdAtupdatedAt は入力しない)
  • 「ほぼ全フィールド使うけど、これだけは不要」というケース
// 新規作成時は id がまだ無いので除外
async function createUser(data: Omit<User, "id">): Promise<User> { ... }

Record<K, T> — キーと値のペアでオブジェクトを定義

const userCache: Record<string, User> = {
  uyfhfghgf6: { id: "uyfhfghgf6", name: "James", role: "admin" },
};

使いどころ

  • ID をキーにしたルックアップテーブル / キャッシュ
  • API レスポンスを id でインデックスした Map 的構造
  • enum や union 型をキーにした設定マッピング
// ロールごとの表示ラベルを定義
const roleLabels: Record<User["role"], string> = {
  admin: "管理者",
  editor: "編集者",
  viewer: "閲覧者",
};

この Record<User["role"], string> パターンは、ロールを追加したときに漏れがあるとコンパイルエラーになるので非常に実用的です。


Exclude<T, U> — Union型から特定の値を除外

type NonAdminRoles = Exclude<User["role"], "admin">;
// "editor" | "viewer"

使いどころ

  • 権限チェックで「admin 以外」を型で表現
  • 特定のステータスを除いた処理の分岐
  • APIのレスポンス型から特定のケースを除外

Extract<T, U> — Union型から特定の値を抽出

type OnlyAdmin = Extract<User["role"], "admin" | "root">;
// "admin"

Exclude の逆で、両方に共通する型だけを取り出します

使いどころ

  • 2つの権限セットの共通部分を求める
  • 既存の Union 型からサブセットを安全に切り出す

NonNullable<T> — null / undefined を除外

type ValidEmail = NonNullable<User["email"]>;
// string(undefined が除外される)

使いどころ

  • オプショナルなフィールドが「存在することが確定した後」の型として
  • find()Map.get() の結果を絞り込んだ後の型
const email: string | undefined = user.email;

if (email != null) {
  // ここでは email は string 型(TSの制御フロー解析で絞られる)
  // 型を明示的に表現したい場合に NonNullable が使える
  sendEmail(email as NonNullable<User["email"]>);
}

まとめ

Utility Type ざっくり説明 よくある用途
Partial<T> 全プロパティをオプショナルに PATCH リクエスト、部分更新
Required<T> 全プロパティを必須に バリデーション後の型
Readonly<T> 全プロパティを読み取り専用に APIレスポンスの保持
Pick<T, K> 指定プロパティだけ抽出 コンポーネントの props
Omit<T, K> 指定プロパティを除外 POST リクエスト(id除外)
Record<K, T> キーと値のペアを定義 キャッシュ、ルックアップ
Exclude<T, U> Unionから除外 「admin以外」の表現
Extract<T, U> Unionから抽出 共通権限の取得
NonNullable<T> null/undefined を除外 オプショナル確定後の型

どれも標準で使えるので、ライブラリの追加は不要です。まずは Partial / Pick / Omit あたりから日常的に使ってみると、型定義の重複がかなり減ると思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?