3
Author: Dmitri Pavlutin
Translator: Frontend Xiaozhi
Source: dmitripvlutin

There are dreams and dry goods. search 1616f7f33d9474 [Great Move to the World] Follow this brushing wit who is still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line factory interview complete test sites, materials and my series of articles.

We use two objects to describe the wages of two code farmers:

const salary1 = {
  baseSalary: 100_000,
  yearlyBonus: 20_000
};
 
const salary2 = {
  contractSalary: 110_000
};

Then write a function to get the total salary

function totalSalary(salaryObject: ???) {
  let total = 0;
  for (const name in salaryObject) {
    total += salaryObject[name];
  }
  return total;
}
totalSalary(salary1); // => 120_000
totalSalary(salary2); // => 110_000

If it is yours, how do you declare the salaryObject totalSalary() function to accept objects with string keys and numeric values?

answer to 1616f7f33d95a7 is to use an index signature!

Next, let's take a look at what TypeScript index signatures are and when they are needed.

1. What is an index signature

index signature is to classify objects with unknown structure when only the key and value types are known.

It is in full compliance with the salary parameter, because the function should accept salary objects of different structures, and the only requirement is that the attribute value is a number.

We use the index signature to declare the salaryObject parameter

function totalSalary(salaryObject: { [key: string]: number }) {
  let total = 0;
  for (const name in salaryObject) {
    total += salaryObject[name];
  }
  return total;
}
 
totalSalary(salary1); // => 120_000
totalSalary(salary2); // => 110_000

{[key: string]: number} is an index signature, which tells TypeScript that salaryObject must be an string type 0616f7f33d968c as the key and number as the value.

2. Index signature syntax

The syntax of the index signature is quite simple and looks similar to the syntax of the attribute, but there is a little difference. We only need to write the key type in square brackets, not the attribute name: { [key: KeyType]: ValueType } .

Below are some examples of index signatures.

string type is key and value.

interface StringByString {
  [key: string]: string;
}
 
const heroesInBooks: StringByString = {
  'Gunslinger': '前端小智',
  'Jack Torrance': '王大志'
};

string type is a key, the value can be string , number or boolean

interface Options {
  [key: string]: string | number | boolean;
  timeout: number;
}
 
const options: Options = {
  timeout: 1000,
  timeoutMessage: 'The request timed out!',
  isFileUpload: false
};

The signature key can only be a string `, number or symbol`. Other types are not allowed.

image.png

3. Precautions for Index Signature

There are some precautions for index signatures in TypeScript, which need to be paid attention to.

3.1 Non-existent attributes

What happens if you try to access a non-existent property of an object whose { [key: string]: string }

As expected, TypeScript inferred the type of the value to be string . But check the runtime value, it is undefined :

image.png

According to the TypeScript prompt, the value variable is of string , but its runtime value is undefined .

The index signature just maps a key type to a value type, nothing more. If this mapping is not made correctly, the value type may deviate from the actual runtime data type.

To make the input more accurate, mark the index value as string or undefined . In this way, TypeScript will realize that the property you are accessing may not exist

image.png

3.2 string and number keys

Suppose there is a dictionary of numeric names:

interface NumbersNames {
  [key: string]: string
}
 
const names: NumbersNames = {
  '1': 'one',
  '2': 'two',
  '3': 'three',
  // ...
};

Accessing values via string keys is as expected:

image.png

Will it make an error if I use the number 1

image.png

No, it works normally.

When used as a key in a property accessor, JavaScript implicitly forces the number to be a string ( names[1] is the same as names['1'] TypeScript will also enforce this force.

You can think that [key: string] is the same as [key: string | number]

4. Comparison of index signature and Record<Keys, Type>

TypeScript has a utility type Record<Keys, Type> , which is similar to an index signature.

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

That's the question... When do you use Record<Keys, Type> and when do you use index signature ? At first glance, they look very similar

We know that the index signature only accepts string , number or symbol as the key type. If you try to use, for example, a union of string literal types as a key in an index signature, this is an error.

image.png

Index signatures are universal in terms of keys.

But we can use the union of string literals to describe the keys in Record<keys, Type>

type Salary = Record<'yearlySalary'|'yearlyBonus', number>
 
const salary1: Salary = { 
  'yearlySalary': 120_000,
  'yearlyBonus': 10_000
}; // OK

Record<Keys, Type> is to be specific to the key problem.

It is recommended to use index signatures to annotate common objects, for example, the key is a string type. However, when you know the key in advance, use Record<Keys, Type> to annotate specific objects. For example, the string literal 'prop1' | 'prop2' is used for the key value.

Summarize

If you don't know the object structure you are dealing with, but you know the possible key and value types, then the index signature is what you need.

The index signature consists of the index name and its type in square brackets, followed by a colon and value type: { [indexName: KeyType]: ValueType } , KeyType can be a string , number or symbol , and ValueType can be any type.

~~End, I am Shuwanzhi, and I wrote that this One Piece's latest painting "Tianwangshan" has been updated super exciting, I am going to chase it, see you in the next issue!

possible bugs in 1616f7f33d9d93 editing cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .

Forgive : 1616f7f33d9dbd https://dmitripavutin.com/typescript-index-signatures/

comminicate

The article is continuously updated every week, and you can search on [Daily Move to the World] Read it for the first time, reply [Benefits] are multiple front-end videos waiting for you, this article GitHub https://github.com/xiaozhiqq449245884 has been included, welcome to Star.


王大冶
68.1k 声望105k 粉丝