当尝试解析对象中的对象时,如下所示:
let attribute: keyof Test
for (attribute in data) {
if (typeof data[attribute] != 'string') {
data[attribute]['numberProperty'] = 3
}
}
具有以下数据:
var data: Test = {
stringProperty: "someString",
objectProperty: {
numberProperty: 13
}
}
这个接口:
interface Test {
stringProperty: string
objectProperty: {
numberProperty: number
}
}
我得到了以下错误:
Element implicitly has an 'any' type because expression of type '"numberProperty"' can't be
used to index type 'string | { numberProperty: number; }'.
Property 'numberProperty' does not exist on type 'string | { numberProperty: number; }'.(7053)
由于这个错误抱怨字符串不能被解析为对象,我尝试通过逻辑地导出它并只允许对象通过来将其从等式中移除:
for (attribute in data) {
if (typeof data[attribute] != 'string') { // This line is supposed to remove the string
data[attribute]['numberProperty'] = 3
}
}
但是,这并不奏效,我该怎么办呢?
如果你想看到错误发生的过程,这里有一个 typescript 练习场
1条答案
按热度按时间jogvjijk1#
您希望检查表达式
data[attribute]
到narrow,检查其表观类型从联合string | { numberProperty: number }
到{ numberProperty: number }
。但仅当键属于单个已知文本类型时,才支持对属性访问进行收缩。由于attribute
本身是联合类型("stringProperty" | "objectProperty"
),因此不会发生此类收缩。microsoft/TypeScript#10530存在一个长期存在的问题,即请求支持缩小所有
obj[key]
表达式的范围,即使key
不是单一文本类型...例如string
、联合或generic。(最初的问题实际上是关于所有带括号的属性访问,但当带括号的属性是单个字符串文字时,这部分已经得到修复,所以obj["prop"]
现在以obj.prop
相同的方式缩小了范围,但是这个问题仍然没有解决,需要跟踪其他情况。)在不降低编译器性能的情况下做到这一点并不容易,所以这个特性仍然缺失。除非这种情况发生变化,否则您需要解决它。建议的解决方法是,如果可能,将要缩小范围的表达式复制到它自己的变量,因为变量可以按预期缩小范围。在您的示例中,如下所示:
其编译没有错误,因为
val
确实通过检查从string | { numberProperty: number }
缩小到{ numberProperty: number }
。Playground代码链接