TypeScript 给出编译错误“对象可能'未定义'”,但仅适用于类变量而不是作用域变量

TypeScript gives compile error "Object is possibly 'undefined'." but only with class variable and not scope variables

提问人:Luke Vo 提问时间:11/8/2023 更新时间:11/8/2023 访问量:38

问:

在启用了 TypeScript 的 TypeScript 中(TypeScript playground):strict

type Foo = { a: number; b: number; }

class Bar {

    #a?: Foo;

    bar() {
        const a = this.#a?.a;
        if (!a) {return;}

        // Error: Object is possibly 'undefined'.
        const b = this.#a.b;
    }

    bar2() {
        const obj = this.#getFoo();

        const a = obj?.a;
        if (!a) {return;}

        // No error:
        const b = obj.b;       
        console.log(b);
    }

    #getFoo() : Foo | undefined {
        return undefined;
    }

}

为什么 TS 正确理解了这一点,因为 这不可能 ;但不是在?我缺少逻辑案例吗?bar2()obj.bundefinedthis.#a.bbar()

在 中,如果我分配它,它也会成功编译。bar()const tmp = this.#a


更新:显然它与变量的可变性有关。如果我使用 ,错误也会显示。let obj = this.#getFoo()obj

TypeScript 编译器错误未 定义

评论


答:

3赞 mandy8055 11/8/2023 #1

ts 编译器不能保证值在两个属性访问之间不会改变,因为 TypeScript 假设类属性的值可以随时更改,即使在连续的两行代码之间也是如此,即 TypeScript 不能确保 的值在两行之间保持不变。this.#athis.#a

在该方法中,obj 的值被分配给 的结果,这是一个局部变量。TypeScript 可以保证 obj 的值在两次属性访问之间不会改变,因此它不会抱怨。bar2()this.#getFoo()

在上次更新中,当您使用 时,TypeScript 假定 obj 的值可能会在两个属性访问之间更改,因为它是可变的。结果,错误也会出现。let obj = this.#getFoo()obj

现在,要解决此问题,您可以分配给局部常量变量。像这样:this.#a

bar() {
        const obj = this.#a; // <----Notice this
        const a = obj?.a;
        if (!a) {return;}

        // Error: Object is possibly 'undefined'.
        const b = obj.b;
    }

打字稿游乐场

上下文引用

评论

1赞 Luke Vo 11/8/2023
我读了你的例子,把我的大脑搞砸了,以为我发现了一个错误的案例。事实证明你是对的 😅
1赞 Luke Vo 11/8/2023
没什么,我认为流程分析是错误的,所以我尝试了一堆场景,并搞砸了其中的一些。