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できない問題を解決する

推薦する

ローカルのMySQLをサーバーデータベースに移行する方法

Linux の scp コマンド (Windows では scp は使用できません) と、mysql...

HTMLページ間で値を渡す問題の解決策

初めてこのエッセイを使ったとき、私はかなりぎこちなく感じましたhtmlファイルコードをコピーコードは...

getdata テーブル テーブル データ 結合 mysql メソッド

パブリック関数 json_product_list($where, $order){ グローバル ...

MySQL SQL文を最適化するためのヒント

十分に最適化されていない、またはパフォーマンスが極端に低い SQL ステートメントに直面した場合、通...

vscodeを使用してReact Native開発環境を構築する方法を教えます

質問コードにはプロンプトがありません: RN 開発に不慣れな、フロントエンド以外の学生の多くは、「ど...

DockerでKafkaをデプロイする方法

目次1. Dockerをビルドする2. コンテナに入る3. 設定ファイルを変更する4. Kafkaを...

ウェブページを開いて数秒後に他のページにリダイレクトする

これを実現するには、次のコードを追加するだけです。方法1: メタを使用する使用方法: <Met...

Vue で配列をクリアするいくつかの方法 (要約)

目次1. はじめに2. データを消去するいくつかの方法2.1 ref() の使用2.2 スライスの使...

MySQLデータベーストリガーの詳細な説明

目次1 はじめに2 トリガーの紹介3 トリガーを作成する4 トリガーを表示5. トリガーの削除6 結...

HTML の相対パスと絶対パスの違いの分析

HTML 初心者は、ファイルを正しく参照する方法という問題によく遭遇します。たとえば、HTML ペー...

Nginx 1つのドメイン名で複数のプロジェクトにアクセスする方法の例

背景最近、複数のプロジェクトを展開する際に、1 つのドメイン名で複数のプロジェクトにアクセスする方法...

v-model 双方向バインディングデータを実装する vue カスタム コンポーネントのサンプル コード

プロジェクトでは、プロジェクトが呼び出すカスタム パブリック コンポーネントに遭遇します。通常、pr...

CSS3 でクールなスライス画像カルーセル効果を実現

今日は、CSS を使用してクールな画像カルーセル コンポーネントを作成する方法を学びます。その原理は...

Linuxでのcrontabの使い方と注意点の詳しい説明

Crontab は定期的な実行を設定するために使用されるコマンドです。そのデーモン プロセスは cr...

デザイン理論:計画、リソース、コミュニケーションの問題について

<br />多くの中小企業ではこの問題は発生しません。中小企業はデザイナーをサポートし、...