这两段代码看起来是等价的,但只有一段出现类型错误
function test(arr: string[]) {
// Error here
const el = arr[0];
if (el === 2) { }
/*
^ Invalid check of number literal `2` against string [1] because number literal `2` [2] is incompatible with string [1]. [incompatible-type]
*/
// No error here
if (arr[0] === 2) { }
}
这种行为背后的动机是什么?
正如我所见,在第一部分中,您在比较之前将
arr[0]
的值分配给单独的变量,这会阻止 Flowtype
根据比较上下文细化 arr[0]
的类型,在第二部分中,直接在arr[0]
上进行比较,让Flowtype
进行类型细化,确定arr[0]
的类型可以缩小到number
。
让我解释一下,在第一部分中,您将
arr[0]
的值分配给 el
变量,因此 Flowtype
将 el
的类型推断为 string
,因为 arr
参数已注释作为字符串数组,然后将 el
与数字 2
进行比较,因为 el
被推断为字符串,因此 Flowtype
会引发错误,因为您正在将字符串与数字进行比较,并且会发生此错误因为 Flowtype
对类型安全要求严格,并希望防止潜在的类型错误,但在第二部分中,您直接将 arr[0]
与数字 2
进行比较。因此 Flowtype
根据 arr[0]
参数的类型注释将 string
的类型推断为 arr
,并且由于您直接将其与数字 2
进行比较,因此 Flowtype
不会引发错误并且当然,这是因为 Flowtype
使用称为 type refinement
的过程来根据使用变量的上下文来缩小变量的类型!