无法通过使用变量作为索引名称来访问 TypeScript 中对象的字段,除非声明为常量

问题描述 投票:0回答:1

我不明白为什么前两个打印输出有效,而另外两个则产生错误。

const index1 = "name";
const holder: { field: string; } = { field: "name" };
const index2 = holder.field;

const target = { name: "beep" } as MyType;

console.log(target["name"]);
console.log(target[index1]);

console.log(target[holder.field]);
console.log(target[index2]);

错误提示:

TS7053:元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引类型“MyType”。
在“MyType”类型上找不到带有“string”类型参数的索引签名。

如何通过来自非常量的变量名获取字段?

我还没有找到以我认可的方式解决这个具体问题的好答案。最令人困惑的是,在这两种情况下,我都使用字符串来获取对象中的字段。唯一的区别是 const 声明。

我尝试根据示例添加

as const

,没有任何区别。

字段值来自该接口。它绝对是一个字符串。在上面的示例中,我什至简化了类型定义。

export interface SortInfo { field: string; direction: number; }

我试图从中获取字段的对象本身是由该接口声明的。

export interface MyType { id: string; name: string; type: number; ... }

	
angular typescript
1个回答
0
投票

就像

target["foobar"]

无法编译一样,如果

target[key]
的类型是
key
string
也会编译。
您需要密钥的类型为 

keyof typeof target

,或者在您的情况下为

keyof MyType
,即
"id" | "name" | "type" | ...
您可以将 

holder

定义为

{ field: keyof MyType; }
:
const holder: { field: keyof MyType; } = { field: "name" };
console.log(target[holder.field]); // This works fine

如果该类型确实应该是
SortInfo

,那么你可以使用

export interface SortInfo {
  field: keyof MyType;
  direction: number;
}

当然,如果 
MyType

可以是不同的东西,你会使用泛型:

export interface SortInfo<T> {
  field: keyof T;
  direction: number;
}

	
© www.soinside.com 2019 - 2024. All rights reserved.