Code Fix

上級

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パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)