[K in keyof T] マップ型
最終更新:2026-10-22
[K in keyof T] マップ型
マップ型は「キーを巡り、値を変換」します。[K in keyof T]: boolean は T の各キー K に対して同名の新しいプロパティを生成します。型を一括で変えるための組み立てラインであり——Partial が省略可能に、Readonly が読み取り専用にするのは、どちらも1行のマップの産物です。
| グループ | ジェネリクス |
|---|---|
| 種類 | 構文 |
| strict モード | 不要 |
ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。
📝 構文
type BooleanFlags<T> = {
[K in keyof T]: boolean;
};
// 修飾子の組み合わせ:readonly で読み取り専用に、-? で任意性を除去
type MyReadonly<T> = { readonly [K in keyof T]: T[K] };
type Concrete<T> = { [K in keyof T]-?: T[K] };
⚙️ パラメータ
| [K in keyof T] | 走査節:K が T の各キー名に順番に束縛されます |
|---|---|
| T[K] | 値の変換:新しいプロパティの型で、自由に演算できます(boolean、T[K] | null、ラッパー型など) |
| readonly / ? / -? | 修飾子:マップのときに readonly や省略可能マークを付けたり外したりできます |
戻り値:マップ型は新しいオブジェクト型を返します。キーの集合は T と同じ(as でろ過や改名も可能)で、値の型はマップのルールに従って変換されます。
▶ サンプル
下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:
出力:
{"dark":true,"beta":false,"newNav":true}
true false
(トランスパイル後の実行出力。flags.dark から得られるのは本来の true リテラルではなく boolean です——マップのルールがすべてのフィールドを boolean に変えました)
💡 ポイント
ℹ️ 説明 組み込みの Partial、Readonly、Pick、Record はすべてマップ型で実装されています。[K in keyof T] を読めば、ユーティリティ型の章の半分が読めたも同然です。
💡 ヒント as 節はキー名の変更やろ過ができます。{ [K in keyof T as NewKey<K>]: T[K] } はテンプレートリテラルで改名し、as never はそのキーを削除します——キーと値を一緒に変える上級テクニックです。
⚠️ 注意 keyof T をマップするのは同態的(元の修飾子を保持)ですが、普通のユニオンを直接マップする(Record 風)と省略可能/読み取り専用は保持されません——「私の ? はどこへ行った?」の大半はこの違いのせいです。
🏷️ 関連ジェネリクス
💡 関連ケース
ケースは今後追加予定です。
📚 関連チュートリアル
❓ よくある質問
Q マップ型とインデックスシグネチャの違いは何ですか?
A インデックスシグネチャ [k: string]: T は「どんなキーでも T」と宣言し、キー名は固定されません。マップ [K in keyof T] は既知のキーを1つずつ複製し、型はキーごとに正確です。前者は寛容なフォールバック、後者は正確な変換です。
Q 一部のキーだけをマップできますか?
A できます。as でろ過する([K in keyof T as K extends "id" ? never : K])か、先に Pick/Omit してからマップします。キー集合の切り詰めは as 節で行われます。
Q マップ型で関数や配列を作れますか?
A 作れます。{ [K in keyof T]: (v: T[K]) => void } は一連のコールバックを生成し、{ [K in keyof T]: T[K][] } はすべてのフィールドを配列にします——値位置の変換は単純な型に限りません。