使用instanceof时Flow为何触发未覆盖代码警告?
为什么Flow会在特定if顺序下触发未覆盖代码警告?
你之前的逻辑刚好搞反啦!不过核心确实和typeof与instanceof的行为差异,以及Flow的类型推导规则有关。让我拆解清楚:
首先,先明确两个判断的本质区别,以及它们的逻辑关系:
typeof str === 'string':仅对原始字符串值(比如'hello world'这种直接声明的字符串)返回true,此时str不是对象。str instanceof String:仅对通过new String()创建的包装对象(比如new String('hello'))返回true,此时typeof str的结果是'object',而非'string'。
划个重点:这两个判断是完全互斥的——一个值不可能同时满足两个条件,也不存在谁包含谁的情况。
接下来结合你的代码和Flow的类型推导来分析:
你的函数参数标注的是str: string,在Flow的类型系统里,string特指原始字符串类型,不包含String包装对象。
代码示例1的问题
const isStr = (str: string): boolean=> { if(typeof str === 'string') return true; if(str instanceof String) return true; return false }
Flow能识别到:对于string类型的参数,第一个typeof判断永远为true,函数会直接返回true,后面的if(str instanceof String)分支永远不会被执行到。所以Flow会标记这段代码为未覆盖的死代码,触发警告。
代码示例2为什么没有警告
const isStr = (str: string): boolean=> { if(str instanceof String) return true; if(typeof str === 'string') return true; return false }
同样,Flow知道string类型的参数不可能是String的实例,所以第一个instanceof判断永远为false,代码会进入第二个typeof判断分支——而这个分支是一定会执行的,不存在死代码,所以Flow不会触发警告。
如果你的实际需求是同时支持原始字符串和String包装对象,应该把参数类型改成string | String,这样两个判断分支都会被Flow识别为有效代码,不会触发未覆盖警告。
内容的提问来源于stack exchange,提问作者Tuucan
相关产品推荐
相关产品推荐

