计算属性名称时,空推断不起作用(Typescript)

时间:2019-12-19 10:20:57

标签: typescript

我正在尝试使用mixins,因此我想使用“私有”成员,因此我不会覆盖基类上的任何内容。据我了解,符号是执行此操作的正确方法。但是,我遇到了一个令人困扰的问题:

const sym = Symbol.for('__a');

class A {
    [sym]: number | undefined;
    __staticProp: number | undefined;


    foo() {
        const value = this[sym] ? this[sym] : 4; //typeof value is 'number | undefined' - but it should be just 'number'
        const value2 = this.__staticProp ? this.__staticProp : 4; //typeof value2 is just number, as expected
    }
}

有人可以阐明这种行为吗?我在做错什么吗?

1 个答案:

答案 0 :(得分:1)

是的,这是TypeScript的当前设计限制。您要尝试的操作称为“基于控制流的缩小”。在表达式foo.bar ? foo.bar.baz : qux中,编译器会将foo.bar的类型 narrow 缩小为?之后和:之前的真值,因为它知道如果控制流到达那里,那么foo.bar是正确的。

如您所见,这适用于字符串文字类型的“普通”属性,即使使用括号表示法也是如此,如microsoft/TypeScript#26424中所实现。不幸的是,not implemented支持唯一的符号键属性。有一个existing issue, microsoft/TypeScript#23135要求提供支持,但是在跳过该实现的实现出现之前,它已作为一般括号符号问题的副本被关闭。如果您真的有强烈的想法,也许应该提出一个新的问题(参考现有问题)。

在那之前,该怎么办?最简单的方法是重构,以便编译器真正知道undefined是不可能的。像x ? x : y这样的表达式几乎总是可以简化为x || y,并且不需要控制流分析。所以:

    const value: number = this[sym] || 4; // okay

希望有所帮助;祝你好运!

Link to code