**类型脚本版本:**1.8.9
代码
class Example {
protected width = 0;
constructor(sibling: Example | HTMLCanvasElement) {
console.log(sibling.width);
}
}
**预期行为:**无错误。
**实际行为:**错误:x1m0n1x
发生此错误的原因是width
属性在Example
上是protected
,而在HTMLCanvasElement
上是public
。但是,此错误会造成混淆,原因有二:
1.在这种情况下,width
属性可用于两个组件属性。如果sibling
参数的类型为Example
或HTMLCanvasElement
,则代码将编译。
1.错误消息没有解释类型上不存在该属性的原因。要理解该错误,需要了解只有在具有相同隐私级别的联合类型上才有可用的属性,即使这些属性在活动上下文中的组件类型中是可访问的。
我不确定在访问联合类型上的潜在保护属性时,如果该属性在所有组件类型上都是可访问的,是否会出现期望的行为是编译错误的情况。我想不出任何情况,所以我认为理想的情况是编译器在这里不抛出错误。然而,我认为这是一个足够的解决方案来改善错误消息。
(如果之前有人报道/讨论过这个问题,我很抱歉。我搜索了一下,但没有找到任何与此完全一致的内容。)
3条答案
按热度按时间6tqwzwtp1#
复制这些属性或在新类型(联合类型)上公开它们将打破这些假设
@mhegazy这是设计的一部分还是仅仅是实现细节?如果我们缩小类型,我们仍然可以访问
width
属性:一个更好的错误消息可能会有所帮助,但根本问题是联合类型实际上应该允许对成员访问考虑词法作用域。
inb24sb22#
这是设计的一部分还是仅仅是实现细节?如果我们缩小类型,我们仍然可以访问width属性:
这是通过设计实现的。收缩采用联合类型,并删除一些组成部分。结果类型是变量在块中所具有的类型。在这些情况下,对
width
的访问对于两种类型都是正确的。一个更好的错误消息可能会有所帮助,但根本问题是联合类型实际上应该允许对成员访问考虑词法作用域。
TS有一个结构化的类型系统。在赋值压缩期间,以及在收缩、推理等期间,经常会比较类型的属性。在每个属性上保持一个“范围”很快就变成了一个不可跟踪的问题。