Javascript 与不相交的结合相混淆
我试图让可能的对象联合起来,并将它们相互转换 但typescript和flow都无法识别布尔值是真是假,其他什么都没有,所以可以将布尔值指定给需要真文本或假文本的对象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
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的。这是一个盲点的类型系统,它发挥它太安全的案件是有效的。