TypeScript 等位型别中同层级的私用/受保护属性

fiei3ece  于 2022-10-29  发布在  TypeScript
关注(0)|答案(3)|浏览(119)

**类型脚本版本:**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参数的类型为ExampleHTMLCanvasElement,则代码将编译。
1.错误消息没有解释类型上不存在该属性的原因。要理解该错误,需要了解只有在具有相同隐私级别的联合类型上才有可用的属性,即使这些属性在活动上下文中的组件类型中是可访问的。
我不确定在访问联合类型上的潜在保护属性时,如果该属性在所有组件类型上都是可访问的,是否会出现期望的行为是编译错误的情况。我想不出任何情况,所以我认为理想的情况是编译器在这里不抛出错误。然而,我认为这是一个足够的解决方案来改善错误消息。
(如果之前有人报道/讨论过这个问题,我很抱歉。我搜索了一下,但没有找到任何与此完全一致的内容。)

6tqwzwtp

6tqwzwtp1#

复制这些属性或在新类型(联合类型)上公开它们将打破这些假设
@mhegazy这是设计的一部分还是仅仅是实现细节?如果我们缩小类型,我们仍然可以访问width属性:

class Example {
    protected width = 0;
    constructor(sibling: Example | HTMLCanvasElement) {
        if (sibling instanceof Example) {
            sibling.width;
        } else {
            sibling.width;
        }
    }
}

一个更好的错误消息可能会有所帮助,但根本问题是联合类型实际上应该允许对成员访问考虑词法作用域。

inb24sb2

inb24sb22#

这是设计的一部分还是仅仅是实现细节?如果我们缩小类型,我们仍然可以访问width属性:
这是通过设计实现的。收缩采用联合类型,并删除一些组成部分。结果类型是变量在块中所具有的类型。在这些情况下,对width的访问对于两种类型都是正确的。
一个更好的错误消息可能会有所帮助,但根本问题是联合类型实际上应该允许对成员访问考虑词法作用域。
TS有一个结构化的类型系统。在赋值压缩期间,以及在收缩、推理等期间,经常会比较类型的属性。在每个属性上保持一个“范围”很快就变成了一个不可跟踪的问题。

相关问题