Record<K, V>
最終更新:2026-10-22
Record<K, V> Record
Record<K, V> は「キーが K、値が V」のオブジェクト型を構築します。K にはリテラルのユニオン(列挙の対応表)も string/number(開かれたキャッシュオブジェクト)も取れます。手書きのインデックスシグネチャに比べ、Record はキーと値の型を一箇所で宣言し、どこでも再利用できます。
| グループ | ユーティリティ型 |
|---|---|
| 種類 | 型 |
| strict モード | 不要 |
ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。
📝 構文
type Record<K extends string | number | symbol, V> = {
[P in K]: V;
};
// 使い方
type Timeout = Record<"dev" | "staging" | "prod", number>;
type Cache = Record<string, number>;
⚙️ パラメータ
| K | キーの型です。リテラルのユニオンなら各キーが必須になり、string/number/symbol なら開かれたキーの集合になります |
|---|---|
| V | すべてのキーが共用する値の型です |
戻り値:マップ型です。K の各メンバーがキーになり、値の型はすべて V です。
▶ サンプル
下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:
出力:
15000 3000
128
(トランスパイル後の実行出力。Record<Env, number> は3つのキーがすべて揃っていることを要求し、staging を落とすと error TS2739 になります)
💡 ポイント
ℹ️ 説明 実装は type Record<K, V> = { [P in K]: V } です。マップ型が K の各キーを V に写します。したがって Record<"a"|"b", number> では a と b の両方が必須になります。
⚠️ 注意 Record<string, V> は任意のキーへのアクセスに対して V を返します(V | undefined ではなく。実際にはそのキーが存在しないかもしれません)。strict モードでは noUncheckedIndexedAccess を有効にするとインデックスアクセスの結果に undefined が加わり、実態に近づきます。
💡 ヒント 「キーと値の入れ替え」やオブジェクトからキーのユニオンを逆算したいときは、keyof typeof obj でキーのユニオンを取り、Record<keyof typeof obj, NewValue> で同型の表を作れます。列挙値を表示用のテキストへ写すときによく使われます。
🏷️ 関連ユーティリティ型
💡 関連ケース
ケースは今後追加予定です。
📚 関連チュートリアル
❓ よくある質問
Q Record<K, V> と { [key: string]: V } のインデックスシグネチャの違いは何ですか?
A K がリテラルのユニオンのとき、Record はすべてのキーが出現することを要求します(完備性のチェック)。インデックスシグネチャにはこの制約がありません。K が string の場合は型の上で両者は等価です。「キーが必ず揃うこと」が必要ならリテラルのユニオンを使った Record を選びましょう。
Q Record の値はキーごとに違えても構いませんか?
A Record はすべてのキーが1つの V を共用することを要求します。キーごとに値の形が異なる場面ではマップ型を使いましょう。{ [K in Env]: { url: string; retries: number } } のように書くか、先に interface で宣言してから Record<Env, Config> で再利用します。
Q Record の代わりに Map を使うべきですか?
A 場面次第です。キーが固定、JSON へのシリアライズが必要、完備性チェックの恩恵を受けたいなら Record。キーが実行時に動的に増える、任意の型のキーが必要、追加と削除が頻繁なら Map<string, number>。両者は型の意味論が異なるため、気安く混同して比べないでください。