Programmingフルスタック開発者

TypeScriptにおけるkeyof typeofとは何ですか? それらの組み合わせはどのように機能し、実務でどのように使用されますか?

Hintsage AIアシスタントで面接を突破

回答。

keyoftypeof演算子は、TypeScriptの型付けにおける強力なツールです。これらを組み合わせることで、型を動的に構築し、安全な関数を作成し、オブジェクトの構造を最大限に柔軟に表現できます。

問題の背景

TypeScriptにおけるtypeofは変数の型を推論するために使用され、keyofはオブジェクトまたは型のすべてのキーのユニオンを返します。これらを組み合わせることで、動的に宣言されたオブジェクトと相互関連のある型を扱うことができます。

課題

これらの演算子がないと、オブジェクト、enum、マッピングテーブルを扱う際には、型や値のキーを手動で繰り返す必要が多く、これが非同期のエラーを引き起こし、コードの保守性を複雑にします。

解決策

typeofを使用して変数の値から型を取得し、keyofを用いてそのキーすべてのユニオン型を構築します。結果として、型付けの自動化が得られます。

コード例:

const ERRORS = { NOT_FOUND: 'Not found', UNAUTHORIZED: 'Unauthorized', SERVER_ERROR: 'Server error', }; // typeofを通じて型を取得し、keyofでオブジェクトのすべてのキーを取得する function getErrorMessage(code: keyof typeof ERRORS): string { return ERRORS[code]; }

主な特徴:

  • 手動での更新なしに、厳密に関連したkey-value型の構築を支援します。
  • オブジェクトのキーを扱う関数の型付けを可能にします。
  • キーと型の間の非同期の問題を排除します。

ひねりのある質問。

typeofによって取得されたオブジェクトの値は、union型のキーとして自動的に使用されますか?

いいえ、typeofはオブジェクトの構造の型を返し、値は返しません。値のunionを取得するには、値の型を別途取得する必要があります。

enumに対してtypeofは何を返し、enumに対してkeyof typeofは何を返しますか?

enumに対してtypeofはenumオブジェクトの型(key-valueとvalue-keyの両方向)を返し、keyof typeofはそのオブジェクトの文字列/数値キーのユニオンを提供します。たとえば:

enum Colors { Red = 'R', Blue = 'B' } type ColorKeys = keyof typeof Colors; // 'Red' | 'Blue'

keyof typeofを使って、オブジェクトのキーを受け取る関数の型安全なパラメータリストを取得できますか?

はい、その方法で、許可されたキーのみを受け取る関数を作成できます。これは、オブジェクトのキーを扱う際のエラーを防ぎます。

const config = { mode: 'dark', lang: 'ru' }; type ConfigKeys = keyof typeof config; // 'mode' | 'lang' function useConfig(key: ConfigKeys) { // ... }

タイプエラーとアンチパターン

  • keyof typeofが配列の値に適用できるという誤解 — 配列にとってはインデックスであり、値ではありません。
  • typeofが型レベルで動作し、runtime値を返さないという誤解。
  • 明示的に宣言されていない型に対する適用が、型推論を壊す原因になります。

実生活の例

ネガティブケース

APIのステータスを扱う定数で、手動で文字列キーの型を定義する:

type StatusCodes = 'OK' | 'FAIL' | 'PENDING'; function isKnownStatus(code: StatusCodes) { /* ... */ }

利点:

  • 許可されている文字列が明確に表示されます。

欠点:

  • リストを更新する際に手動で型を変更する必要がある; 非同期とエラーの可能性。

ポジティブケース

keyof typeofを使用してリストの自動サポート:

const STATUS = { OK: 1, FAIL: 0, PENDING: 2 }; type StatusKeys = keyof typeof STATUS; function checkStatus(key: StatusKeys) { /* ... */ }

利点:

  • ステータスの追加/削除時に型が自動的に更新されます。
  • 型と値の非同期の問題がありません。

欠点:

  • 非常に複雑な構造を扱う際には、これらの型の理解には経験と注意が必要です。