所以我有以下代码:
type Something =
| { t: 'A', src: string }
| { t: 'B', src: string }
| { t: 'C', src: number };
const f = (o: Something): string =>
o.t === 1
? o.src
: 'a-string';
我希望当 o.t
为1时返回 o.src
时会出现错误,因为我从未定义过 t
可以是一个数字 . 因此,如果 t
是数字,则流不知道 o.src
的类型是什么 . 但它没有任何错误 . 我在这里错过了什么?
这是flow/try .
对于记录,TypeScript version正确抛出错误 . 虽然错误消息不是那么有用 .
为了澄清一点,如果我改为使用 o.t === 'F'
,那么flow会很乐意抛出以下错误:
9:ot ==='F'^所有分支都不兼容:具有匹配字符串文字F 1的属性t的对象与字符串文字A 2不兼容 . 或者具有与字符串文字F 1匹配的属性t的对象与字符串不兼容文字B [3] . 或者具有匹配字符串文字F 1的属性t的对象与字符串文字C [4]不兼容 . 参考文献:9:o.t ==='F'^ 1 4:| {t:'A',src:string} ^ 2 5:| {t:'B',src:string} ^ [3] 6:| {t:'C',src:number}; ^ [4]
我不知道为什么,但它只是不一致的行为,如果我使用的是未在类型中定义的值,我希望看到一些错误 . 你知道,就像一块无法访问的代码 .
3 回答
这取决于
===
的语义 . 根据ECMA specification,运算符的定义如下(至少是重要的位):您实际上不必查看步骤1.您的表达式
o.t === 1
可以看作:只会对该表达式的第一部分进行求值,因为它可能会显示为false . Flow知道你实际上永远不会在这里将数字与字符串进行比较 .
正如其他人已经回答的那样,你应该使用带有Flow的
==
.Flow通常希望您使用
==
,因为它无论如何都可以告诉您不安全的强制 . 如果使用==
编写此示例,则会出现预期的错误(4个错误):如果在
? o.src
处检查o.src
的类型,则会引发错误,但它确实理解这种情况是不可能的,因此只能返回一个字符串 .请参阅Peter Hall的答案,了解为什么流程正在这样做 . 似乎主要原因是您使用了
===
运算符 .===
相等的第一步似乎是检查两个项目的类型是否相同 . 没有它们是相同的,Flow标记分支已空 . 似乎使用==
可能更适合捕捉这些东西(只要你打开了不安全的强制警告 . )旁注:如果您使用的是Flow.com/try,则可以将鼠标悬停在表达式上以显示类型 .