类型防护未从计算的属性解析

时间:2019-07-12 07:08:50

标签: typescript casting

由于某种原因,TypeScript不能将 type-guard 放在计算属性中。

以下代码可正确解析:

class Timeout {
    protected timer? : NodeJS.Timeout

    start() {
        if (this.timer !== undefined) { // <-- type-guard
            clearTimeout(this.timer)
        }
    }
}

但是,当将if条件提取到计算属性(见下文)时,TypeScript不会对其进行解析。

class Timeout {
    protected timer? : NodeJS.Timeout

    start() {
        if (this.hasStarted) {
            clearTimeout(this.timer)
        }
    }

    get hasStarted() {
        return this.timer !== undefined 
    }
}

如何强制类型防护解决而不必将值cast更改为non-null类型?

2 个答案:

答案 0 :(得分:1)

属性比较不被视为类型保护。

如果要内联键入guard,可以执行以下操作:

class Timeout {
    protected timer? : NodeJS.Timeout

    start() {
        const timer = this.timer
        if (timer !== undefined) {
            clearTimeout(timer)
        }
    }
}

或者您可以让编译器知道您更聪明:

class Timeout {
    protected timer? : NodeJS.Timeout

    start() {
        if (this.timer !== undefined) {
            clearTimeout(this.timer!)
        }
    }
}

答案 1 :(得分:1)

Typescript通常不会跨函数边界遵循代码来检查副作用。因此,将检查移到单独的功能将终止流程分析。唯一的例外是自定义类型防护,它具有特殊的语法,可让编译器知道参数的类型已更改。

class Timeout {
    timer? : NodeJS.Timeout
    hasStarted() :this is this & { timer : NodeJS.Timeout } {
        return this.timer != null;
    }
    start() {
        if (this.hasStarted()) {
            clearTimeout(this.timer)
        }
    }
}

注意:这仅适用于公共领域。

注意:我并不一定建议这样做,但出于完整性和评论需求的原因而提出。