keyof typeofで作ったキーの型は、存在しないキーを渡すとエラーになる
keyof typeof objは、実行時のオブジェクトobjが実際に持つキーだけを表すunion型(リテラル型の集合)になります。定義時に存在しないキー文字列を渡すと、その型に含まれないためエラーになります。
エラーメッセージの読み方
main.ts(6,22): error TS2345: Argument of type '"blue"' is not assignable to parameter of type '"red" | "green"'.
main.ts- ファイル名
6- 行番号
22- 列番号 — この位置でtscが検査に失敗しました
TS2345- エラーコード — 検索するとTypeScriptの解説が見つかります
Argument of type '"blue"' is not assignable to parameter of type '"red" | "green"'.- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 const colors = { red: "#f00", green: "#0f0" }; 2 type ColorKey = keyof typeof colors; 3 function getColor(key: ColorKey): string { 4 return colors[key]; 5 } 6 console.log(getColor("blue")); ^
main.ts(6,22): error TS2345: Argument of type '"blue"' is not assignable to parameter of type '"red" | "green"'.
ColorKeyはcolorsが実際に持つキー("red" | "green")だけを表します。"blue"はcolorsに存在しないキーです。
直し方: "blue" を "red" にします。
広告
広告スロット(未設定)
パターン2
1 const rates = { jpy: 1, usd: 150 }; 2 type CurrencyKey = keyof typeof rates; 3 function getRate(key: CurrencyKey): number { 4 return rates[key]; 5 } 6 console.log(getRate("eur")); ^
main.ts(6,21): error TS2345: Argument of type '"eur"' is not assignable to parameter of type '"jpy" | "usd"'.
CurrencyKeyはratesの実際のキーだけです。"eur"はratesに存在しないので渡せません。
直し方: "eur" を "usd" にします。
パターン3
1 const sizes = { small: 1, large: 3 }; 2 type SizeKey = keyof typeof sizes; 3 function getSize(key: SizeKey): number { 4 return sizes[key]; 5 } 6 console.log(getSize("medium")); ^
main.ts(6,21): error TS2345: Argument of type '"medium"' is not assignable to parameter of type '"small" | "large"'.
sizesには"medium"というキーはありません。SizeKeyは実際に存在するキーの集合に限られます。
直し方: "medium" を "small" にします。
よくある誤解
「キーはただの文字列だから、存在確認は実行時にやればいい」という発想は、keyof typeofパターンでは不要になります。存在しないキーの指定自体を、実行前にtscが検出してくれます。
まとめ
keyof typeofで作ったキーの型は、存在しないキーを渡すとエラーになるは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。