元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型

目录

Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type

  1. 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型
  2. 元素隐式具有“任何”类型,因为索引表达式不是“数字”类型
如果在 处访问数组时出现错误index,请单击第二个副标题。

元素隐式具有“any”类型,因为类型“string”的表达式不能用于索引类型

string当我们使用a 索引具有特定键的对象时,会出现错误“Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type”。

要解决该错误,请键入string作为对象键之一的。

下面是错误如何发生的示例。

索引.ts
const str = 'name' as string; const obj = { name: 'Bobby Hadz', country: 'Chile', }; // ⛔️ Error: Element implicitly has an 'any' type // because expression of type 'string' can't be used // to index type '{ name: string; }'. // No index signature with a parameter of type 'string' // was found on type '{ name: string; }'.ts(7053) obj[str];

变量str有一个类型string,这可以是任何string

name当我们尝试访问具有 a和
属性
的对象时出现错误
country

TypeScript 告诉我们类型string太宽泛,并非所有字符串都是对象中的键,因此我们必须确保
特定字符串是对象的键之一。

使用类型断言解决错误

解决错误的第一种方法是使用
类型断言

索引.ts
const str = 'name' as string; const obj = { name: 'Bobby Hadz', country: 'Chile', }; // 👇️ "Bobby Hadz" console.log(obj[str as keyof typeof obj]); // 👇️ type T = "name" | "country" type T = keyof typeof obj;

我们使用类型断言向 TypeScript 表明该str变量是一个
仅包含对象键的
联合类型。

现在 TypeScript 允许我们在不抛出错误的情况下访问特定的属性。

我们使用keyof typeof来获取对象键的联合类型。

如果您直接使用类型,则只需使用keyof MyType获取对象键的联合。

索引.ts
const str = 'name' as string; interface Person { name: string; country: string; } const obj: Person = { name: 'Bobby Hadz', country: 'Chile', }; console.log(obj[str as keyof Person]); // 👉️ "Bobby Hadz" // 👇️ type T = "name" | "country" type T = keyof Person;
请注意,我们使用了keyof Personand not因为它是一个类型而不是一个对象。 keyof typeof PersonPerson

输入变量来解决错误

解决这个问题的更好方法是键入变量,str
keyof Person向 TypeScript 表明它string永远只是对象的键之一。

索引.ts
interface Person { name: string; country: string; } // 👇️ this will only ever be one of object's keys const str: keyof Person = 'name'; const obj: Person = { name: 'Bobby Hadz', country: 'Chile', }; console.log(obj[str]); // 👉️ "Bobby Hadz"

现在我们不必在代码中使用类型断言。

当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

使用它们时,我们有效地告诉 TypeScript 值X将是类型的X,不用担心它。如果我们错了,这可能会导致运行时错误。

这是另一个示例,说明如何将值键入为对象的键之一。

索引.ts
interface Person { name: string; country: string; } const obj1: Person = { name: 'Bobby Hadz', country: 'Chile', }; interface AccessPerson { keyName: keyof Person; // 👈️ only one of Person's keys } const obj2: AccessPerson = { keyName: 'country', }; console.log(obj1[obj2.keyName]); // 👉️ "Chile"

我们正在使用该obj2.keyName属性访问obj1.

为了能够做到这一点,我们必须将keyName属性输入obj2为 type keyof Person

keyName中的属性只能obj2nameor
的值
country,因此 TypeScript 允许我们安全地访问 中的属性obj1

这是必要的,因为并非世界上所有的字符串值都是特定对象中的键。为了让 TypeScript 让我们访问对象的属性,我们必须说服它该字符串是对象的键之一。

这是对错误的最类型安全的解决方案,因为如果我们试图将 的值更改obj2.keyName为不兼容的类型,就会出现错误。

索引.ts
interface Person { name: string; country: string; } interface AccessPerson { keyName: keyof Person; } const obj2: AccessPerson = { keyName: 'country', }; // ⛔️ Error: Type '"hello"' is not // assignable to type 'keyof Person'.ts(2322) obj2.keyName = 'hello';

尝试设置obj2.keyNamename或以外的任何其他值country会导致错误。


当函数参数的隐式
类型
any.

元素隐式具有 ‘any’ 类型,因为索引表达式不是 ‘number’ 类型

当使用非数字值对数组进行索引时,会出现错误“元素隐式具有‘任何’类型,因为索引表达式不是‘数字’类型”。

要解决该错误,如果存储键值对或使用类型断言,请使用对象。

元素隐式具有任何类型的索引表达式而不是数字

以下是错误发生方式的 2 个示例。

索引.ts
const arr = ['a', 'b', 'c']; // ⛔️ Error: Element implicitly has an 'any' type // because index expression is not of type 'number'.ts(7015) const result = arr['a']; // -------------------------------------------------- const obj: { [key: number]: string } = { 0: 'a', 1: 'b', }; // ⛔️ Error: Element implicitly has an 'any' type because // index expression is not of type 'number'.ts(7015) const result2 = obj['a'];

在第一个示例中,我们尝试使用字符串访问索引处的数组元素。

在第二个示例中,我们有一个带有数字键的对象,并尝试使用字符串键对其进行索引。

访问索引处的数组

如果您尝试访问索引处的数组元素,请使用从零开始的数字。

索引.ts
const arr = ['a', 'b', 'c']; const result = arr[0]; console.log(result); // 👉️ "a"

如果用于索引数组或对象的值的类型不正确,请使用类型断言。

索引.ts
const arr = ['a', 'b', 'c']; const result = arr['1' as unknown as number]; console.log(result); // 👉️ "b"


当我们有关于 TypeScript 不知道的值类型的信息时,使用
类型断言。

我们有效地告诉 TypeScript 该值是类型的number,不用担心它。

抑制整个项目的错误

如果您想抑制any整个项目的隐式索引错误,您可以在tsconfig.json
文件中执行此操作。

tsconfig.json文件
{ "compilerOptions": { "suppressImplicitAnyIndexErrors": true, // ... rest } }


suppressImplicitAnyIndexErrors
选项设置为 时
trueany在对对象或数组进行索引时不会报告隐式错误。

使用带有索引签名的对象来存储键值对

如果您尝试存储键值对,请使用具有索引签名和字符串键的对象。

索引.ts
type Person = { [key: string]: any; }; const obj: Person = { name: 'Bobby Hadz', }; obj.age = 30; obj.salary = 100; obj.tasks = ['develop', 'test']; console.log(obj['age']); // 👉️ 30 console.log(obj['salary']); // 👉️ 100

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

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

您还可以显式添加您事先知道的属性名称和类型。

索引.ts
type Person = { [key: string]: any; name: string; // 👈️ add name property of type string country: string; // 👈️ add country property of type string }; const obj: Person = { name: 'Bobby Hadz', country: 'Germany', }; obj.age = 30; obj.salary = 100; obj.tasks = ['develop', 'test']; console.log(obj['age']); // 👉️ 30 console.log(obj['salary']); // 👉️ 100

我们显式键入了namecountry属性。这为指定的属性提供了更好的类型安全性和 IDE 自动完成功能。

额外资源

您可以通过查看以下教程来了解有关相关主题的更多信息: