0Pricing
TypeScript Academy · レッスン

インデックスシグネチャとRecord

インデックスシグネチャとRecordユーティリティ型のどちらを使うか判断します。

「インデックスシグネチャとRecord」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

マップに型を付ける2つの方法

TypeScriptで辞書を記述する一般的な方法は2つあります。{ [k: string]: V } のようなインデックスシグネチャと、組み込みのユーティリティ型 Record<K, V> です。両者は重なる部分が多いものの、見え方が異なります。

Recordユーティリティ型

Record<K, V> は、キーが K で値が V であるオブジェクト型を構築します。キーに string を指定すると、文字列インデックスシグネチャと同等になります。

type Scores = Record<string, number>
const game: Scores = { alice: 10, bob: 7 }
console.log(game.alice)

インデックスシグネチャと同等

これら2つの型は同じ形状を表します。Record<string, number> と { [key: string]: number } は、任意の文字列キーに対して互換性があります。

type A = Record<string, number>
type B = { [key: string]: number }
const a: A = { x: 1 }
const b: B = a // assignable both ways
console.log(b.x)

リテラルキーのユニオン型を指定したRecord

Record の本当の強みは、リテラルキーの有限なユニオン型と組み合わせたときに現れます。列挙したすべてのキーが必須であるオブジェクトを生成します。これはインデックスシグネチャでは表現できません。

type Role = "admin" | "editor" | "viewer"
type Perms = Record<Role, boolean>
const p: Perms = { admin: true, editor: true, viewer: false }
console.log(p.admin)

キーの不足を検出できる

各リテラルキーが必須になるため、1つでも記述し忘れるとコンパイルエラーになります。これは、インデックスシグネチャだけでは提供できない強力な保証です。

type Role = "admin" | "editor" | "viewer"
// const bad: Record<Role, boolean> = { admin: true, editor: true }
// Error: property viewer is missing

インデックスシグネチャでは任意のキーを許可する

これに対して、インデックスシグネチャには上限がありません。どこにも記述されていないキーも追加でき、存在が必須のものはありません。

type Open = { [key: string]: number }
const o: Open = {}      // no keys required
o.anything = 1          // any key allowed
console.log(o.anything)

有限のキー集合にはRecordを優先する

キーが既知で有限の集合である場合は、リテラルのユニオン型を指定した Record のほうが明確で安全です。存在するキーを正確に示し、すべてのキーがそろっていることを強制できます。

type Direction = "north" | "south" | "east" | "west"
type Moves = Record<Direction, number>
const m: Moves = { north: 1, south: 0, east: 2, west: 0 }
console.log(m.east)

無制限のキー集合ではどちらでもよい

キーが無制限で、実行時に決まる場合は、Record<string, V> とインデックスシグネチャのどちらも使えます。簡潔さを理由に Record を選ぶチームもあれば、明示性を理由にシグネチャを選ぶチームもあります。

type Cache1 = Record<string, string>
type Cache2 = { [url: string]: string }
const c: Cache1 = {}
c["/home"] = "<html>"
console.log(c["/home"])

Recordは単なるマップ型

内部では、Record<K, V> はマップ型として { [P in K]: V } と定義されています。これを知っておくと、リテラルのユニオン型ではキーが必須になり、string ではインデックスシグネチャになる理由がわかります。

// lib definition (simplified):
// type Record<K extends string | number | symbol, V> = { [P in K]: V }
type Flags = Record<"a" | "b", boolean>
const f: Flags = { a: true, b: false }
console.log(f.a)

名前付きキーとキャッチオール

インデックスシグネチャでは、1つのインターフェース内でキャッチオールと固定キーを組み合わせられます。両方が必要な場合に便利です。Record だけでは、必須の名前付きキーとオープンなキャッチオールを同じようにきれいに組み合わせることはできません。

interface Response {
  status: number
  [header: string]: number | string
}
const r: Response = { status: 200, "x-id": "abc" }
console.log(r.status)

実際の選び方

原則として、有限で既知のキーには、完全性のチェックができる Record<Union, V> を使います。無制限のキーにはどちらの形式でも構いません。名前付きキーとキャッチオールの両方が必要なら、インターフェース内のインデックスシグネチャを使います。

type Status = "ok" | "error"
type Messages = Record<Status, string>
const msg: Messages = { ok: "done", error: "failed" }
console.log(msg.ok)

理解度チェック

Recordとインデックスシグネチャの違いについての理解度を確認しましょう。

まとめ

Record<string, V> は文字列インデックスシグネチャと同等ですが、リテラルキーのユニオン型を指定した Record では、列挙したすべてのキーが必須になり、コンパイル時に記述漏れを検出できます。有限で既知のキーには Record<Union, V> を、無制限のキーにはどちらの形式も使えます。名前付きキーとキャッチオールが必要な場合は、インデックスシグネチャを使います。内部では、Record はマップ型 { [P in K]: V } です。

よくある質問

「インデックスシグネチャとRecord」レッスンは無料ですか?

はい。「インデックスシグネチャとRecord」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「インデックスシグネチャとRecord」で何を学びますか?

インデックスシグネチャとRecordユーティリティ型のどちらを使うか判断します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「インデックスシグネチャとRecord」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. インデックスシグネチャの定義
  2. 文字列インデックスシグネチャと数値インデックスシグネチャ
  3. 既知のキーと動的なキーの組み合わせ
  4. インデックスシグネチャとRecord
← TypeScript Academyに戻る