在不验证属性的情况下测试联合变量的类型

Testing type of union variable without verifying properties

我正在尝试检查联合类型变量值的类型。

/* @flow */

type A = {
  a: number, 
  b: number
}

type B = {
  c: string
}

const fun1: (A | B) => void = (x) => {
  if (x.a) {
    x.a
    x.b // Doesn't work
  }
  if (x.b) {
    x.b
    x.a // Doesn't work
  }
  if (x.c) {
    x.c
  }
}

检查单个属性是唯一的方法吗?在上面的示例中,已知如果 x.a,则也 x.b。有没有办法检查 A 类型或 B 类型所以我可以写

const fun1: (A | B) => void = (x) => {
  if (typeof x === 'A') { // Cannot compare the result of `typeof` to string literal `A` because it is not a valid `typeof` return value.
    x.a // Works
    x.b // Works
  }
}

您的代码失败,因为默认情况下 Flow 对象类型允许未指定的属性,因此例如以下是好的:

let a: A = {
  a: 1,
  b: 2,
  c: "",
};

因此,根据您当前的定义,A 类型 符合 B 类型。

为避免这种情况,您需要使 AB exact object types,因此 Flow 知道它们不允许额外的随机属性。例如

type A = {|
  a: number, 
  b: number
|}

type B = {|
  c: string
|}