打字稿类型警卫和胖箭头功能

时间:2018-12-05 22:01:31

标签: typescript typeguards

这不能正确编译吗?突出显示的行中出现错误"Property 'hello' does not exist on type 'object'.“。

我可以在粗箭头功能之外访问g.hello

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

let g : object;

if (g instanceof Test) {
    () => {
        g.hello();    ////// ERROR HERE /////
    };
}

2 个答案:

答案 0 :(得分:2)

类型守卫对变量(或其他任何事物)所做的缩小将不会跨越功能边界。这是设计限制。

解决此问题的一种方法是将g分配给一个新变量,该变量将根据缩小的范围推断出其类型。在箭头函数中访问新变量将按预期工作:

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

let g : object;

if (g instanceof Test) {
    const gTest = g;
    () => {
        gTest.hello();
    };
}

答案 1 :(得分:0)

let + 箭头函数

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare let g : object;

if (g instanceof Test) {
    () => {
        g.hello(); // error
    };
}

g 在定义函数时是 Test,但在函数运行时 g 可能不是 Test

const + 箭头函数

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare const g : object;

if (g instanceof Test) {
    () => {
        g.hello(); // ok
    };
}

g 是不可变的,g 在函数定义后始终是 Test

const + 正则函数

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare const g : object;

if (g instanceof Test) {
    function f() {
        g.hello(); // error
    };
}

在底层实现中,正则函数 f 由 ES5 var 定义,而不是 ES6 letvariable hoisting 提升 f 的声明,当 g 可能不是 Test 时。