在类型上找不到带有“string”类型参数的索引签名
No index signature with a parameter of type ‘string’ was found on type
当我们使用类型的值来string
索引具有特定键的对象时,会出现“No index signature with a parameter of type ‘string’ was found on type”的错误。
要解决该错误,请string
使用 键入 作为对象的键之一
keyof typeof obj
。
下面是错误如何发生的示例。
const key = 'country' as string; const obj = { name: 'Bobby Hadz', country: 'Germany', }; // ⛔️ Error: No index signature with a parameter of type // 'string' was found on type '{ name: string; country: string; }'.ts(7053) console.log(obj[key]);
该key
变量的类型为string
,这可以是任何类型string
。
name
当我们尝试访问具有和属性的对象时,我们收到了错误country
。
string
类型太宽泛,并非所有字符串都是对象中的键。我们必须确保特定字符串是对象的键之一。使用类型断言解决错误
解决该错误的第一种方法是使用
类型断言。
const key = 'country' as string; const obj = { name: 'Bobby Hadz', country: 'Germany', }; // 👇️ "Germany" console.log(obj[key as keyof typeof obj]); // 👇️ type OnlyKeys = 'name' | 'country' type OnlyKeys = keyof typeof obj;
我们使用类型断言向 TypeScript 指示该key
变量不是类型string
,而是仅
包含对象键的联合类型。
现在,TypeScript 允许我们访问该属性而不会引发错误。
我们使用keyof typeof来获取对象键的联合类型。
如果您直接使用类型,则只需用于keyof MyType
获取对象键的并集。
interface Employee { name: string; country: string; } const obj: Employee = { name: 'Bobby Hadz', country: 'Germany', }; const key = 'country' as string; // 👇️ "Germany" console.log(obj[key as keyof Employee]); // 👇️ type OnlyKeys = 'name' | 'country' type OnlyKeys = keyof Employee;
keyof Employee
and not ,因为它是类型而不是对象。 keyof typeof Employee
Employee
key
正确输入变量
解决此问题的更好方法是输入变量key
as ,
keyof Employee
以向 TypeScript 指示string
只会成为对象的键之一。
interface Employee { name: string; country: string; } const obj: Employee = { name: 'Bobby Hadz', country: 'Germany', }; // 👇️ key can only be one of the object's keys const key: keyof Employee = 'country'; // 👇️ "Germany" console.log(obj[key as keyof Employee]);
现在我们不必使用类型断言。
当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。
X
将是类型Y
,而不必担心它。如果我们错了,这可能会导致运行时错误。这是另一个示例,说明如何键入仅作为对象键之一的值。
interface Employee { name: string; country: string; } const obj1: Employee = { name: 'Bobby Hadz', country: 'Germany', }; interface AccessEmployee { keyName: keyof Employee; // 👈️ one of Employee's keys } const obj2: AccessEmployee = { keyName: 'country', }; // 👇️ "Germany" console.log(obj1[obj2.keyName]);
我们使用该obj2.keyName
属性来访问 中的属性obj1
。
为了能够做到这一点,我们必须将keyName
属性键入obj2
为 类型keyof Employee
。
keyName
中的属性只能obj2
具有值name
or
country
,因此 TypeScript 允许我们安全地访问 中的特定属性
obj1
。
这是针对该错误最类型安全的解决方案,因为如果我们尝试将 的值更改obj2.keyName
为不兼容的类型,就会收到错误。
interface Employee { name: string; country: string; } interface AccessEmployee { keyName: keyof Employee; // 👈️ one of Employee's keys } const obj2: AccessEmployee = { keyName: 'country', }; // ⛔️ Type '"something else"' is not assignable // to type 'keyof Employee'.ts(2322) obj2.keyName = 'something else';
尝试设置为或 以外obj2.keyName
的任何其他值会导致类型检查器发出错误。name
country
使用类型谓词来解决错误
如果您正在使用函数,您还可以使用类型谓词来确定字符串是否是该类型中的键之一。
type Employee = { id: number; name: string; salary: number; }; const employee: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, }; function isAnEmployeeProperty(str: string): str is keyof Employee { return ['id', 'name', 'salary'].includes(str); } const myIdentifier = 'name' as string; if (isAnEmployeeProperty(myIdentifier)) { console.log(employee[myIdentifier]); // 👉️ "Bobby Hadz" }
语法str is keyof Employee
是
类型谓词。
parameter is Type
形式。 parameter
如果它与原始类型兼容,这允许 TypeScript 将变量缩小到特定类型。
在isAnEmployeeProperty
函数中,我们简单地检查传入的字符串是否是对象的键之一并返回结果。
如果我们进入if
块,TypeScript 知道myIdentifier
变量是对象中的键之一,并允许我们使用它来索引对象。
我还写了一篇关于
在 TS 中使用索引签名的详细指南。
额外资源
您可以通过查看以下教程来了解有关相关主题的更多信息: