Javascript 与不相交的结合相混淆

Javascript 与不相交的结合相混淆,javascript,typescript,flowtype,Javascript,Typescript,Flowtype,我试图让可能的对象联合起来,并将它们相互转换 但typescript和flow都无法识别布尔值是真是假,其他什么都没有,所以可以将布尔值指定给需要真文本或假文本的对象 type Aa = { isFetching: false, isFailed: false, isFetched: false } type Bb = { isFetching: true, isFailed: false, isFetched: false } type Cc = { isFet

我试图让可能的对象联合起来,并将它们相互转换

但typescript和flow都无法识别布尔值是真是假,其他什么都没有,所以可以将布尔值指定给需要真文本或假文本的对象

type Aa = {
  isFetching: false,
  isFailed: false,
  isFetched: false
}

type Bb = {
  isFetching: true,
  isFailed: false,
  isFetched: false
}

type Cc = {
  isFetching: true,
  isFailed: true,
  isFetched: false
}
type Dd = {
  isFetching: false,
  isFailed: true,
  isFetched: false
}

type Data = Aa | Bb | Cc | Dd

function thisWorks(data: Data): Data {
  if (data.isFailed) {
    return {
      isFetching: true,
      isFailed: true,
      isFetched: data.isFetched
    }
  } else {
    return {
      isFetching: true,
      isFailed: false,
      isFetched: data.isFetched
    }
  }
}

function thisDoesNot(data: Data): Data {
  return {
    isFetching: true,
    isFailed: data.isFailed,
    isFetched: data.isFetched
  }
}
这是不是bug


问题在于,对象文字既不与
Bb
兼容,也不与
Cc
兼容,因为
isFailed
boolean
(由于该字段对联合的所有成员都是公共的,因此它将变为
true | false
,即
booelan

最简单的解决方案是对联合使用类型断言。这将保留一些检查,但允许进行分配:

function thisDoesNot(data: Data): Data {
    return {
        isFetching: true,
        isFailed: data.isFailed,
        isFetched: data.isFetched
    } as Data
}
这将是一个错误:

function thisDoesNot(data: Data): Data {
    return {
        isFetching: 1,
        isFailed: data.isFailed,
        isFetched: data.isFetched
    } as Data
}
但我们确实丢失了多余的财产检查,这是有效的:

function thisDoesNot(data: Data): Data {
    return {
        excess: 1,
        isFetching: true,
        isFailed: data.isFailed,
        isFetched: data.isFetched
    } as Data
}

将对象强制转换为数据并不能解决这个问题,将对象强制转换为返回类型仍然很奇怪,因为它应该在以太中强制转换为返回类型way@thecotne我的答案仅对typescript有效,不适用于flow,我假设您的问题是针对typescript的。这是一个盲点的类型系统,它发挥它太安全的案件是有效的。