目录
Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type
index
,请单击第二个副标题。元素隐式具有“any”类型,因为类型“string”的表达式不能用于索引类型
string
当我们使用a 索引具有特定键的对象时,会出现错误“Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type”。
要解决该错误,请键入string
作为对象键之一的。
下面是错误如何发生的示例。
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
太宽泛,并非所有字符串都是对象中的键,因此我们必须确保
特定字符串是对象的键之一。
使用类型断言解决错误
解决错误的第一种方法是使用
类型断言。
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
获取对象键的联合。
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 Person
and not因为它是一个类型而不是一个对象。 keyof typeof Person
Person
输入变量来解决错误
解决这个问题的更好方法是键入变量,str
以
keyof Person
向 TypeScript 表明它string
永远只是对象的键之一。
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 不知道的值类型的信息时,使用类型断言。
X
将是类型的X
,不用担心它。如果我们错了,这可能会导致运行时错误。这是另一个示例,说明如何将值键入为对象的键之一。
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
中的属性只能obj2
有name
or
的值country
,因此 TypeScript 允许我们安全地访问 中的属性obj1
。
这是对错误的最类型安全的解决方案,因为如果我们试图将 的值更改obj2.keyName
为不兼容的类型,就会出现错误。
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.keyName
为name
或以外的任何其他值country
会导致错误。
当函数参数的隐式类型为
any
.
元素隐式具有 ‘any’ 类型,因为索引表达式不是 ‘number’ 类型
当使用非数字值对数组进行索引时,会出现错误“元素隐式具有‘任何’类型,因为索引表达式不是‘数字’类型”。
要解决该错误,如果存储键值对或使用类型断言,请使用对象。
以下是错误发生方式的 2 个示例。
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'];
在第一个示例中,我们尝试使用字符串访问索引处的数组元素。
访问索引处的数组
如果您尝试访问索引处的数组元素,请使用从零开始的数字。
const arr = ['a', 'b', 'c']; const result = arr[0]; console.log(result); // 👉️ "a"
如果用于索引数组或对象的值的类型不正确,请使用类型断言。
const arr = ['a', 'b', 'c']; const result = arr['1' as unknown as number]; console.log(result); // 👉️ "b"
当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。
我们有效地告诉 TypeScript 该值是类型的number
,不用担心它。
抑制整个项目的错误
如果您想抑制any
整个项目的隐式索引错误,您可以在tsconfig.json
文件中执行此操作。
{ "compilerOptions": { "suppressImplicitAnyIndexErrors": true, // ... rest } }
当
suppressImplicitAnyIndexErrors
选项设置为 时true
,any
在对对象或数组进行索引时不会报告隐式错误。
使用带有索引签名的对象来存储键值对
如果您尝试存储键值对,请使用具有索引签名和字符串键的对象。
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 中的索引签名,当我们事先不知道类型属性的所有名称和值的形状时使用。
string
,它将返回一个any
类型的值。您还可以显式添加您事先知道的属性名称和类型。
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
我们显式键入了name
和country
属性。这为指定的属性提供了更好的类型安全性和 IDE 自动完成功能。
额外资源
您可以通过查看以下教程来了解有关相关主题的更多信息: