{[key: string]: any} 在 TypeScript 中是什么意思

TypeScript 中的 { [key: string] : any} 类型

What does {[key: string]: any} mean in TypeScript

{[key: string]: any}语法是 TypeScript 中的索引签名,当我们事先不知道类型属性的所有名称及其值的形状时使用。索引签名指定当一个对象被一个字符串索引时,它返回一个带有any类型的值。

索引.ts
// 👇️ function returning index signature // (a key-value structure with key string and value any) function getObj(): { [key: string]: any } { return { name: 'Tom', age: 30, pizza: true }; } // 👇️ Interface using index signature interface Person { [index: string]: any; } // 👇️ const p1: Person const p1: Person = { name: 'Tom', age: 30 }; // 👇️ Type using index signature type Animal = { [index: string]: any; }; const a1: Animal = { name: 'Alfred', age: 3 };

{[key: string]: any}语法是 TypeScript 中的
索引签名
,当我们事先不知道类型属性的所有名称和值的形状时使用。

示例中的索引签名意味着当一个对象被索引为 astring时,它将返回一个any类型的值。

{[key: string]: string}您可能还会在示例中看到索引签名。它代表一个键值结构,当用 a 索引时string返回一个 type 的值string

索引签名{[key: string]: any}非常宽泛,并没有真正说明索引签名的用途。

让我们看一个更窄的索引签名的示例,以及尝试设置不同类型的值如何导致类型检查器出错。

索引.ts
interface Person { [index: string]: string; } // ⛔️ Error: Type 'number' is not assignable to type 'string'. const p1: Person = { name: 'Tom', age: 30 };

示例中的索引签名意味着当一个对象被索引为 a
string时,它返回一个类型的值string

这就是为什么我们在尝试将属性添加到 typestring值为 type的对象时出错的原因number

您可能会尝试使用索引签名覆盖特定属性的类型。

索引.ts
interface Person { [index: string]: string; // ⛔️ Error: Property 'age' of type 'number' // is not assignable to 'string' index type 'string'. age: number; }

但是age示例中属性的类型与字符串索引的类型不匹配,所以 TypeScript 给了我们一个错误。

在这种情况下,您可以将字符串索引的类型设置为联合。

索引.ts
interface Person { [index: string]: string | number; age: number; name: string; } // 👇️ const p1: Person const p1: Person = { name: 'Tom', age: 30, country: 'Chile' };

索引签名为 type 的值的类型string是 和 的
string并集number

ageand属性name值是联合的子类型,因此我们不会收到错误。

尝试向不在联合中的类型添加属性会导致错误。

索引.ts
interface Person { [index: string]: string | number; age: number; name: string; // ⛔️ Error: Property 'languages' of type 'string[]' is // not assignable to 'string' index type 'string | number'. languages: string[]; }

If the value of the string keys were set to any in the index signature, you
could add properties to the object of any type, since anything is more specific
than any.

index.ts
interface Person { [index: string]: any; age: number; name: string; languages: string[]; } // 👇️ const p1: Person const p1: Person = { name: 'Tom', age: 30, country: 'Chile', languages: ['english', 'spanish'], };

This would be a good way to narrow down the type of some of the properties
that you know ahead of time.

For example, if I try to add an age property to the object that has a type of
string, the type checker would throw an error, because it expects a number.

index.ts
interface Person { [index: string]: any; age: number; name: string; languages: string[]; } // 👇️ const p1: Person const p1: Person = { name: 'Tom', // ⛔️ Error: Type 'string' is not // assignable to type 'number'. age: 'twenty', country: 'Chile', languages: ['english', 'spanish'], };

You can also set an index signature to readonly if you need to prevent
assignment to their indices.

index.ts
interface ReadonlyObj { readonly [index: string]: any; } // 👇️ const p1: Person const p1: ReadonlyObj = { name: 'Tom', }; // ⛔️ Error: Index signature in type 'ReadonlyObj' // only permits reading. p1.name = 'James';

We set the string index’s type to readonly, so the type checker gives us an
error if we try to write to a property that has a string key.