首页 文章

流联合类型不会出错

提问于
浏览
2

所以我有以下代码:

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 回答

  • 1

    这取决于 === 的语义 . 根据ECMA specification,运算符的定义如下(至少是重要的位):

    比较x === y,其中x和y是值,产生真或假 . 这样的比较如下进行:如果Type(x)与Type(y)不同,则返回false . ......其他步骤......

    您实际上不必查看步骤1.您的表达式 o.t === 1 可以看作:

    typeof o.t == typeof 1 && (...other steps...)
    

    只会对该表达式的第一部分进行求值,因为它可能会显示为false . Flow知道你实际上永远不会在这里将数字与字符串进行比较 .

    正如其他人已经回答的那样,你应该使用带有Flow的 == .

  • 3

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

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

    如果在 ? o.src 处检查 o.src 的类型,则会引发错误,但它确实理解这种情况是不可能的,因此只能返回一个字符串 .

    请参阅Peter Hall的答案,了解为什么流程正在这样做 . 似乎主要原因是您使用了 === 运算符 . === 相等的第一步似乎是检查两个项目的类型是否相同 . 没有它们是相同的,Flow标记分支已空 . 似乎使用 == 可能更适合捕捉这些东西(只要你打开了不安全的强制警告 . )

    旁注:如果您使用的是Flow.com/try,则可以将鼠标悬停在表达式上以显示类型 .

相关问题