我正在尝试访问object[property]
,TypeScript抛出了element implicitly has any type
错误。
const getValue = (key: string) => {
const object = {
property0: 14
property1: -3
}
if (!(key in object)) {
throw new Error(`Invalid key: ${key}`)
}
return object[key]
}
如果我们不知道property in object
是否为真,我们必须自己为TypeScript提供索引签名,也就是说,如果我们从该函数中删除了if(!(key in object))
条件,TypeScript * 应该 * 抛出错误,直到我们手动注意到object
的索引签名。
但是看起来,如果我们在编译时知道key
在object
中,当我们执行return语句时,TypeScript不应该为这个函数抛出这样的错误,而是应该推断getValue
的返回类型为number
。
我可以通过手动记录object
的索引签名来解决此问题:
interface ObjectWithOnlyNumberProperties {
[key: string]: number
}
const getValue = (key: string) => {
const object: ObjectWithOnlyNumberProperties = {
property0: 14
property1: -3
}
if (!(key in object)) {
throw new Error(`Invalid key: ${key}`)
}
return object[key]
}
但似乎我不必这样做,而且object[key]
的类型应该在编译时可以推断为typeof property0 | typeof property1
,因为我们知道key in object
是真的。
1条答案
按热度按时间yhqotfr81#
抄袭罗曼·洛朗的评论,完美地回答了这个问题!
在编译时,TypeScript处理的是类型,而不是实际对象。默认情况下,
{ property0: 14, property1: -3 }
的类型为{ property0: number, property1: number }
。TypeScript中的类型是最小的契约一致性,因此就TypeScript所知,{ property0: number, property1: number }
类型可以引用像{ property0: 14, property1: -3, property2: "string" }
这样的实际对象。显然,我们在代码中知道它不会。但是TypeScript并不知道这一点,正如上面的例子所表明的,object[property]
的类型是any
,因为property2
可以是 * 任何 * 类型,而不仅仅是string
。更新:根据geoffrey的评论,如果你使用的是目标库
es2022
或更新版本,你也应该更新上面的代码,使用Object.hasOwn(object, property)
代替property in object
,以防止原型污染。