irpas技术客

Element implicitly has an ‘any‘ type because expression of type ‘any‘ can‘t be u

网络 591

Typescript

let obj = { a: "hey", b: "you", c: "guys" }; for (const k in obj) { console.log(obj[k].toUpperCase()); // error! /* Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ a: string; b: string; c: string; }'. */ }

这里的问题是 TypeScript 中的对象类型是开放的或可扩展的,而不是封闭的或精确的。您可以在 TypeScript 中为对象添加额外的属性,而不会违反其类型。这在某些情况下非常有用:它允许您通过添加属性来扩展接口和子类。但在其他情况下,这是一种痛苦:

编译器将 obj 视为 {a: string, b: string, c: string} 类型的值。由于这种类型并不精确,当你执行 for (const k in obj) 时,编译器知道 k 将采用值“a”、“b”和“c”,但它不知道这些是唯一可能的值:

让 hmm = { a: "hey", b: "you", c: "guys", d: 12345 }; object= hmm ; // no error!

因为值 hmm 匹配 {a: string, b: string, c: string}。 d 属性不违反类型。因此,对于所有编译器都知道的,for (const k in obj) 将枚举“a”、“b”、“c”,谁知道还有哪些其他字符串值。因此,k 的类型不是 keyof typeof obj。它只是字符串。

使用 string 类型的键索引 {a: string, b: string, c: string} 是不安全的。实际上,将 hmm 分配给 obj,调用 (12345).toUpperCase() 时会出现运行时错误。所以编译器警告你是正确的。

有关此问题答案的“官方”版本,请参阅 microsoft/TypeScript#35847。另请参阅为什么 Object.keys() 在 TypeScript 中不返回 keyof 类型?,这是相同的问题,除了使用 Object.keys(obj).forEach(k => …) 而不是 for (const k in obj ) {…}… 它有相同的答案。

如果引入了确切的类型,那么这个问题可能就会消失。对此有一个功能请求:microsoft/TypeScript#12936。但看起来这不会很快发生。

for (k in obj) { console.log(obj[k as keyof typeof obj].toUpperCase()); // okay }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #element #implicitly #has #an #any #type #because #Expression