TypeScriptのインデックスシグネチャの理解に関する簡単な説明

TypeScriptのインデックスシグネチャの理解に関する簡単な説明

2 人のコーダーの給与を表すために 2 つのオブジェクトを使用します。

定数給与1 = {
  基本給: 100_000,
  年間ボーナス: 20_000
};
 
定数給与2 = {
  契約給与: 110_000
};


次に、給与総額を取得する関数を作成します。

関数totalSalary(salaryObject: ???) {
  合計を 0 にします。
  for (const name in salaryObject) {
    合計 += salaryObject[名前];
  }
  合計を返します。
}
totalSalary(給与1); // => 120_000
合計給与(給与2); // => 110_000


あなたなら、文字列キーと数値を持つオブジェクトを受け入れるためにtotalSalary()関数のsalaryObjectパラメータをどのように宣言しますか?

答えは、インデックス署名を使用することです。

次に、 TypeScriptインデックス シグネチャとは何か、そしていつ必要になるのかを見てみましょう。

1. インデックス署名とは何ですか?

インデックス シグネチャの考え方は、キーと値の型のみがわかっている場合に、構造が不明なオブジェクトを型指定することです。

この関数はさまざまな構造のsalaryオブジェクトを受け入れる必要があるため、 salaryパラメータの場合に完全に適合します。唯一の要件は、属性値が数値であることです。

salaryObjectパラメータをインデックスシグネチャで宣言します

関数totalSalary(salaryObject: { [キー: 文字列]: 数値 }) {
  合計を 0 にします。
  for (const name in salaryObject) {
    合計 += salaryObject[名前];
  }
  合計を返します。
}
 
totalSalary(給与1); // => 120_000
合計給与(給与2); // => 110_000


{[key: string]: number}はインデックス シグネチャであり、 TypeScript salaryObjectキーとしてstring 、値としてnumber持つオブジェクトでなければならないことを伝えます。

2. インデックス署名構文

インデックス署名の構文は非常に簡単で、プロパティの構文に似ていますが、違いが 1 つあります。プロパティ名の代わりに、角括弧内にキー タイプを記述します: { [ key: KeyType]: ValueType }。

以下にインデックス署名の例をいくつか示します。

string型はキーと値です。

インターフェースStringByString {
  [キー: 文字列]: 文字列;
}
 
const heroesInBooks: StringByString = {
  「ガンスリンガー」:「フロントエンドの知恵」
  「ジャック・トーランス」:「王大志」
};


string型がキーで、値はstringnumberbooleanのいずれかになります。

インターフェースオプション{
  [キー: 文字列]: 文字列 | 数値 | ブール値;
  タイムアウト: 数値;
}
 
const オプション: オプション = {
  タイムアウト: 1000、
  timeoutMessage: 'リクエストがタイムアウトしました!',
  ファイルアップロード: false
};

署名キーには、 string `、 number 、またはsymbol ` のみを使用できます。その他のタイプは許可されません。

3. インデックス署名に関する注意

TypeScriptのインデックス署名には注意が必要な注意事項がいくつかあります。

3.1 存在しないプロパティ

インデックス署名が { [key: string]: string } であるオブジェクトの存在しないプロパティにアクセスしようとするとどうなりますか?

予想どおり、 TypeScript値の型をstringであると推論します。しかし、実行時の値を確認すると、 undefinedです。

TypeScriptによれば、 value変数は文字stringですが、実行時の値はundefinedです。

インデックス署名は、キー タイプを値タイプにマップするだけであり、それ以上のものではありません。このマッピングが正しく行われないと、値の型が実際の実行時データ型から逸脱する可能性があります。

入力をより正確にするために、インデックス値はstringまたはundefinedマークされます。こうすることで、 TypeScriptアクセスしているプロパティが存在しない可能性があることを認識します。

3.2 文字列と数字キー

数字の名前の辞書があるとします。

インターフェース NumbersNames {
  [キー: 文字列]: 文字列
}
 
定数名: NumbersNames = {
  '1': '1'、
  '2': '2'、
  '3': '3'、
  // ...
};

いいえ、正常に動作します。

JavaScript 、プロパティ アクセサーのキーとして使用される場合、数値は暗黙的に文字列に変換されます ( names[1] names['1' ] と同じです)。 TypeScriptでもこれが強制されます。

[key: string ] は[key: string | number]と同じものと考えることができます。

4. インデックス署名とレコード<キー、タイプ>

TypeScriptには、インデックス署名に似たユーティリティ型Record<Keys, Type>,があります。

const object1: Record<string, string> = { prop: 'Value' }; // OK
const object2: { [key: string]: string } = { prop: 'Value' }; // OK

それで質問は... Record<Keys, Type>,インデックス署名をいつ使用するかということです。一見すると似ているように見える

ご存知のとおり、インデックス署名はキー タイプとしてstringnumber 、またはsymbolのみを受け入れます。たとえば、文字列リテラル型のユニオンをインデックス署名のキーとして使用しようとすると、エラーになります。

インデックス署名はキーに関して汎用的です。

しかし、 Record<keys, Type>内のキーを記述するために文字列リテラルの結合を使用することができます。

type Salary = Record<'yearlySalary'|'yearlyBonus', number>
 
const salary1: 給与 = { 
  '年俸': 120_000,
  '年間ボーナス': 10_000
}; // わかりました


Record<Keys, Type>はキー固有の問題用です。

汎用オブジェクトにはインデックス署名 (キーが文字列型であるなど) を注釈として付けることをお勧めします。ただし、キーが事前にわかっている場合は、 Record<Keys, Type>を使用して、キーに使用される文字列リテラル ' prop1' | 'prop2'などの特定のオブジェクトに注釈を付けます。

要約:

扱っているオブジェクトの構造はわからないが、可能なキーと値の型がわかっている場合は、インデックス署名が必要になります。

インデックス署名は、角括弧で囲まれたインデックス名とその型、それに続くコロンと値の型で構成されます: { [indexName: KeyType]: ValueType }, KeyTypestringnumber 、またはsymbolであり、 ValueType任意の型です。

これで、TypeScript インデックス シグネチャの理解に関するこの記事は終了です。TypeScript インデックス シグネチャに関するその他の関連コンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • TypeScript 環境を構築して VSCode にデプロイする詳細な手順
  • TypeScript をインストール、使用、自動コンパイルする方法に関するチュートリアル
  • vs2022 を使用して .net6 で TypeScript による静的ページをデバッグする

<<:  Mysql はテーブル内の古いデータを定期的にクリアし、いくつかのデータを保持します (推奨)

>>:  MacでDockerがホストマシンにpingできない問題を解決する

推薦する

PrometheusはGrafanaディスプレイを使用してMySQLを監視します

目次Prometheusはエクスポーターを介してMySQLを監視し、Grafanaチャートで表示しま...

dockerがredisを再起動するとmysqlデータが失われる問題を解決する

公式ドキュメント:したがって、mysql は次のように起動する必要があります。 docker run...

純粋な CSS 流星群の背景サンプルコード

GitHubアドレス、気に入ったらスターを付けてくださいプラグインのプレビューチュートリアルコード表...

Vueでショッピングカートのすべての機能を実装する簡単な方法

主な機能は次のとおりです。製品情報を追加する製品情報を変更する単一の製品を削除する複数の製品を削除す...

入力タイプ=テキスト値=str を使用するための不完全なソリューション

今日、非常に奇妙な問題に遭遇しました。次のコードを見てください。 SimpleDateFormat ...

CentOS での Docker の詳細なインストール チュートリアル

DockerにはCEとEEがあり、CE版はコミュニティ版(無料)、EE版はセキュリティを重視したエン...

HTMLページ内の検索機能を完了する

最近、たくさんの人に改変してもらったフレームワークに取り組んでいます。毎日コードを見ていると目が回り...

JavaScript の navigator.userAgent がブラウザ情報を取得するケースの説明

ブラウザはおそらく私たちにとって最も馴染みのあるツールです。 Firefox、Opera、Safar...

WeChatアプレットがユーザーの移動軌跡を記録

目次設定を追加json 構成レイヤー構成の表示論理層の構成位置追跡をオンにする録音を開始開始座標を決...

Linux で ffmpeg をインストールするための詳細なチュートリアル

1. CentOS Linuxにffmpegをインストールする1.ダウンロードして解凍する http...

React で setInterval 関数を使用する例

この記事はWindows 10のシステム環境をベースに、Reactの学習と使用について説明しています...

JavaScriptは入力ボックスコンポーネントを実装します

この記事では、入力ボックスコンポーネントを手動で実装するための具体的なコードを参考までに紹介します。...

Linux 向けの強化されたスクリーンショットと共有ツール: ScreenCloud

ScreenCloud は、必要だとは思わなかった素晴らしい小さなアプリです。デスクトップ Lin...

MySQLクエリトランザクション処理へのノード接続の実装

目次トピックmysqlの追加、削除、変更、クエリを入力しますMySQL トランザクション処理私は M...

Windows 8 での MySQL 5.6.15 のインストールと設定方法のグラフィック チュートリアル

MySQLは私がとても気に入っているデータベースです。今日はWindows 8システムでインストール...