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