类型“X”不能用作 TypeScript 中的索引类型

目录

Type ‘X’ cannot be used as an index type in TypeScript

  1. 类型“X”不能用作 TypeScript 中的索引类型
  2. 类型 ‘undefined’ 不能用作 TS 中的索引类型

如果出现错误“类型‘undefined’不能用作索引类型”,请单击第二个副标题。

类型 ‘X’ 不能用作 TypeScript 中的索引类型

当我们尝试使用不能用于索引数组或对象的类型时,会出现错误“类型不能用作索引类型”,例如非原始类型之一,如String.

要解决该错误,请使用原始(小写)类型,例如numberorstring
键入值时。

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

索引.ts
const obj = { name: 'Bobby Hadz', } // 👇️ using String (capital S) const str: String = 'name'; // ⛔️ Error: Type 'String' cannot be used as an index type.ts(2538) obj[str]

我们使用了String非原始对象类型来对str变量进行类型化,这导致了错误。

我们不能使用非原始类型,如NumberStringBoolean作为
Object索引类型。

使用小写原始类型解决错误

要解决错误,请始终使用number, string, boolean, Record, 类型。

索引.ts
interface Employee { name: string; // 👈️ use string lowercase s } const obj: Employee = { name: 'Bobby Hadz', }; const str = 'name'; console.log(obj[str]); // 👉️ "James Doe"

我们使用原始
字符串
类型来解决错误。

number错误是因为原始的,stringboolean类型与非原始的Number, String,
Boolean,Object不同。

非基本类型是对象,在 TypeScript 中键入值时不应使用。

TypeScript
最佳实践文档

警告在 TypeScript 代码中键入值时切勿使用
NumberStringBoolean或非原始对象。SymbolObject

相反,您应该使用numberstringbooleansymbol类型
Record

该错误消息意味着您在尝试在 TypeScript 中索引数组或对象时无法使用指定的类型。

错误发生的另一个例子

这是错误如何发生的另一个示例。

索引.ts
interface Person { key: String; // 👈️ should be string } const obj1: Person = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; // ⛔️ Error: Type 'String' cannot be used as an index type.ts(2538) obj2[obj1.key]

代码示例显示了使用String非原始对象类型如何导致错误,因为它不能用于在特定属性处索引对象。

索引.ts
interface Person { key: string; // 👈️ using primitive type } const obj1: Person = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; // ✅ Works console.log(obj2[obj1.key as keyof typeof obj2]); // 👉️ "Bobby Hadz"

使用string原始类型解决了这个问题。

String
当您尝试将 type 的值分配给 type 的值
时,会显示错误的原因
string

索引.ts
const str1: String = 'bobbyhadz.com'; // ⛔️ Error: Type 'String' is not assignable to type 'string'. // 'string' is a primitive, but 'String' is a wrapper object. // Prefer using 'string' when possible. const str2: string = str1;

大写的非原始对象,如、 、 和StringNumber等同Boolean
SymbolObjectstringnumberboolean

确保始终使用numberstringbooleansymbol代替Record

类型 ‘undefined’ 不能用作 TS 中的索引类型

当可能用于undefined索引对象或数组的值时,会出现“Type ‘undefined’ cannot be used as an index type”错误。

要解决该错误,请使用类型保护来确保undefined
在索引对象或数组之前该值不是。

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

索引.ts
// 👇️ key is optional (could be undefined) const obj1: { key?: string } = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; // ⛔️ Error: Type 'undefined' cannot be used as an index type.ts(2538) const result = obj2[obj1.key];

我们使用问号将key属性
标记为变量

中的
可选属性obj1

这意味着该obj1.key属性可以是 astring或者它可以有一个
undefined值。

通过错误消息,TypeScript 告诉我们不能使用值来索引对象。 undefined

使用类型保护来解决错误

要解决该错误,请在访问该属性之前检查该值是否不是undefined

索引.ts
// 👇️ key is optional (could be undefined) const obj1: { key?: string } = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; const result = obj1.key != undefined ? obj2[obj1.key as keyof typeof obj2] : ''; console.log(result); // 👉️ "Bobby Hadz"

在访问对象中的属性之前,我们使用
三元运算符来检查obj1.key属性是否为空(null或)。undefined

如果该属性为空,我们只需返回一个空字符串的后备值。

使用if语句解决错误

if您还可以使用充当
类型保护的简单语句

索引.ts
const obj1: { key?: string } = { key: 'name', }; const obj2 = { name: 'Bobby Hadz', }; let result = ''; if (obj1.key != undefined) { result = obj2[obj1.key as keyof typeof obj2]; } console.log(result); // 👉️ "Bobby Hadz"

obj1.key属性保证是块string中的一个if,因此我们可以安全地将其用作索引类型。

使用可能未定义的值来索引数组

undefined当您尝试使用可能的值来索引数组时,也会发生该错误。

索引.ts
const arr = ['a', 'b', 'c']; const num: number | undefined = Math.random() > 0.5 ? 0 : undefined; // ⛔️ Error: Type 'undefined' cannot be used as an index type.ts(2538) arr[num];

变量num可以存储一个number或一个undefined值,而 TypeScript 不会让我们用一个undefined值来索引数组。

索引.ts
const arr = ['a', 'b', 'c']; const num: number | undefined = Math.random() > 0.5 ? 0 : undefined; if (num != undefined) { const result = typeof num !== undefined ? arr[num] : ''; console.log(result); // 👉️ "a" }

该变量保证在块中num是 a ,因此我们可以安全地访问特定索引处的数组。numberif

使用类型断言解决错误

如果所有解决方案都不起作用并且您确定该值为 a number,则可以使用
类型断言

索引.ts
const arr = ['bobby', 'hadz', 'com']; const num: number | undefined = 1; const result = arr[num as number]; // 👈️ type assertion console.log(result); // 👉️ "hadz"

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

我们有效地告诉 TypeScript 该num变量将是 anumber并且不用担心它。

额外资源

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