zukucode
主にWEB関連の情報を技術メモとして発信しています。

TypeScript Recordでキーと値の対応表を型安全に作る

ステータスごとの表示名や色を定義するとき、文字列を自由にキーへ使うと、追加漏れやタイプミスに気付きにくくなります。キーの候補が決まっている対応表にはRecordを利用できます。

ステータスの表示名を定義する

type OrderStatus = 'waiting' | 'shipped' | 'canceled';

const statusLabels: Record<OrderStatus, string> = {
  waiting: '発送待ち',
  shipped: '発送済み',
  canceled: 'キャンセル',
};

const getStatusLabel = (status: OrderStatus): string => statusLabels[status];

Record<OrderStatus, string>は、3つのステータスをキーとし、それぞれの値が文字列であるオブジェクトを表します。

追加漏れを検出する

例えばcanceledを対応表から削除すると、TypeScriptが不足を検出します。定義にないcompletedを追加してもエラーになります。ステータスをUnion型へ追加した際に対応表の更新も促されるため、複数の条件式へ表示名を散らすより変更箇所を見つけやすくなります。

値をオブジェクトにする

type StatusView = {
  label: string;
  tone: 'neutral' | 'success' | 'danger';
};

const statusViews: Record<OrderStatus, StatusView> = {
  waiting: { label: '発送待ち', tone: 'neutral' },
  shipped: { label: '発送済み', tone: 'success' },
  canceled: { label: 'キャンセル', tone: 'danger' },
};

画面側はstatusViews[status]から表示に必要な設定をまとめて取得できます。

一部のキーだけ定義する

すべてのステータスが必要でない場合はPartial<Record<OrderStatus, string>>を使えます。ただし取得結果はstring | undefinedになるので、値がない場合を処理します。

const notes: Partial<Record<OrderStatus, string>> = {
  canceled: '再注文できます',
};

const note = notes.waiting ?? '補足はありません';

APIから届いた任意の文字列は、自動的にOrderStatusにはなりません。候補に含まれるか確認してから対応表のキーに使います。


関連記事