使用括号表示法访问对象属性时的类型缩小中断

Ger*_*ner 5 properties typescript type-narrowing

为什么测试 1 和 2 在这里可以工作,但测试 3 显示编译器错误foo[barConst]++:“对象可能是“未定义”。”?我经常需要通过括号表示法访问属性,因此喜欢为这些属性添加常量,但 TypeScript 不允许这样做。它也不适用于const enums。这是一个错误还是有一个很好的原因导致该错误?

const barConst = 'bar';

interface Foo {
    [barConst]?: number;
}

function test1(foo?: Foo) {
    if (foo && foo.bar) {
        foo.bar++;
    }
}

function test2(foo?: Foo) {
    if (foo && foo['bar']) {
        foo['bar']++;
    }
}

function test3(foo?: Foo) {
    if (foo && foo[barConst]) {
        foo[barConst]++; // compiler error: 'Object is possibly "undefined".'
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

for*_*d04 2

目前似乎不可能通过计算的 propertyNames/文字表达式来缩小属性访问范围。看看这个问题及其PR,还有那个问题

您可以使用字符串文字以括号表示法缩小属性访问范围,例如foo["bar"]. 像这样的动态表达式foo[barConst]不起作用。分配foo[barConst]给变量并工作/缩小该变量是一种替代方法,但需要额外的声明。

在您的情况下,最简单的解决方案是仅使用非空断言运算符来转换表达式!。当您预先检查虚假值时,您在这里是安全的:

function test3(foo?: Foo) {
    if (foo && foo[barConst]) {
        foo[barConst]!++; 
    }
}
Run Code Online (Sandbox Code Playgroud)