流联合类型不会出错

时间:2018-04-26 17:52:28

标签: javascript typescript flowtype union-types

所以我有以下代码:

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]

我不知道为什么,但它只是不一致的行为,如果我使用的是未在类型中定义的值,我希望看到一些错误。你知道,就像一块无法达到的代码。

3 个答案:

答案 0 :(得分:3)

Flow通常希望您使用==因为它无论如何都可以告诉您不安全的强制行为。如果您使用==编写此示例,则会出现预期的错误(4个错误):

const f = (o: Something): string => 
  o.t == 1
    ? o.src 
    : 'a-string';

答案 1 :(得分:3)

这取决于===的语义。根据{{​​3}},运算符的定义如下(至少是重要的位):

  

比较x === y,其中x和y是值,产生true或   假。这样的比较如下进行:

     
      
  1. 如果Type(x)与Type(y)不同,则返回false。
  2.   
  3. ...其他步骤......
  4.   

您实际上不必查看步骤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,则可以将鼠标悬停在表达式上以显示类型。