动态类型测试无法按预期工作 [英] dynamic type tests not working as expected

查看:54
本文介绍了动态类型测试无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是 SSCCE .

我有一个地图容器类,其中使用第一个调用的set方法按需创建内部Map:

I have a map container class where an internal Map is created on demand with the first set method that gets called:

// @flow
'use strict';

class MapContainer {

    map: ?Map<any, any>;

    constructor() {
        this.map=null;
    }

    set(key: any, value: any): ?any {
        if (this.map===null) {
            this.map = new Map();
        }
        let prevValue: ?any;
        if (this.map!=null) { // first check
            prevValue = this.map.get(key);
        }
        if (this.map!=null) { // second check
            this.map.set(key, value);
        }
        return prevValue;
    }
}    
exports.MapContainer = MapContainer;

上面的代码在没有警告的情况下通过了npm run flow.

The above code passes npm run flow with no warnings.

但是,如果我将两个if (this.map!=null)检查合并为一个:

However if I merge the two if (this.map!=null) checks into one:

// @flow
'use strict';

class MapContainer {

    map: ?Map<any, any>;

    constructor() {
        this.map=null;
    }

    set(key: any, value: any): ?any {
        if (this.map===null) {
            this.map = new Map();
        }
        let prevValue: ?any;
        if (this.map!=null) { // merged check
            prevValue = this.map.get(key);
            this.map.set(key, value);
        }
        return prevValue;
    }
}    
exports.MapContainer = MapContainer;

…然后运行流失败,并显示以下消息:

… then running flow fails with the following message:

es6/map-container.js:19
 19:                 this.map.set(key, value);
                 ^^^^^^^^^^^^^^^^^^^^^^^^ call of method `set`. Method cannot be called on possibly null value
 19:                 this.map.set(key, value);
                 ^^^^^^^^ null

es6/map-container.js:19
 19:                 this.map.set(key, value);
                 ^^^^^^^^^^^^^^^^^^^^^^^^ call of method `set`. Method cannot be called on possibly undefined value
 19:                 this.map.set(key, value);
                 ^^^^^^^^ undefined

…这对第19行的访问毫无意义:

… which makes no sense at all as the access on line 19:

this.map.set(key,value)

…仍然被支票覆盖:

… is still covered by the check:

if (this.map!=null)

有什么作用?

推荐答案

问题是对get方法的调用会使优化无效.如果getthis.map设置为null怎么办?流量无法得知,因此假设情况最糟.这是您可以做的:

The problem is that call to get method can invalidates refinement. What if get sets this.map to null? Flow has no way of knowing, so it assumes the worst. Here is what you can do:

class MapContainer {

    map: ?Map<any, any>;

    constructor() {
        this.map=null;
    }

    set(key: any, value: any): ?any {     
        if (!this.map) {
            this.map = new Map();
        }

        const map = this.map;

        let prevValue: ?any;
        if (this.map!=null) {
            prevValue = map.get(key);
            map.set(key, value);
        }
        return prevValue;
    }
}    

这篇关于动态类型测试无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆