Javascript 无标记的不相交并集
我有这种情况,没有办法有意义地改变数据结构。所以我不能添加标签。 有没有一种不用标记就能区分类型的方法?我试着打字,但不起作用。看我的 错误是:Javascript 无标记的不相交并集,javascript,flowtype,Javascript,Flowtype,我有这种情况,没有办法有意义地改变数据结构。所以我不能添加标签。 有没有一种不用标记就能区分类型的方法?我试着打字,但不起作用。看我的 错误是: 5:const doSomethingWithDone=(obj:Done)=>{/*…*/} ^属性“count”。在中找不到属性 10:doSomethingWithDone(结果) ^对象类型 6:const doSomethingWithError=(obj:Error)=>{/*…*/} ^属性“message”。在中找不到属性 12:doS
5:const doSomethingWithDone=(obj:Done)=>{/*…*/}
^属性“count”。在中找不到属性
10:doSomethingWithDone(结果)
^对象类型
6:const doSomethingWithError=(obj:Error)=>{/*…*/}
^属性“message”。在中找不到属性
12:doSomethingWithError(结果)
^对象类型
Flow不像不相交的并集那样优雅地支持这类事情。但是,确切的类型会有所帮助。你例子中的问题是我能做到
const x: Error = {message: 'foo', count: 'bar'};
f(x);
赋值有效,因为我的对象文字满足x
接口。因此,虽然您知道如果某个东西是错误
,它有一个消息
属性,但您不知道它还有什么其他属性。因此,检查count
属性是否存在并不能证明您拥有类型为Done
的有效对象
确切的类型在这里有帮助:
type Result = Done | Error; // a disjoint union type with two cases
type Done = {| count: number |}
type Error = {| message: string |}
const doSomethingWithDone = (obj: Done) => {/*...*/}
const doSomethingWithError = (obj: Error) => {/*...*/}
const f = (result: Result) => {
if (result.count) {
doSomethingWithDone(result)
} else if (result.message) {
doSomethingWithError(result)
}
}
// Expected error. Since Error is an exact type, the count property is not allowed
const x: Error = {message: 'foo', count: 'bar'};
f(x);
()
请注意,除了使类型精确之外,我还必须将您的else
更改为else if
。显然,使用精确类型有一个缺点,即对象不能有无关的字段。但是,如果绝对不能添加鉴别器字段以使用不相交的并集,我认为这是最好的选择
这是有道理的,因为你的打字没有说一个Done
不能有count属性
从某种意义上说,使用精确的对象类型似乎可以部分地起作用,正如您在本文中看到的那样,它确实可以适当地细化。遗憾的是,您还必须在else中进行显式检查
如果
计数
为0
或消息
为”
,此方法将失败。我猜我的答案被否决了,因为乍一看,我的类型似乎改变了你的数据结构,而你说你不能这样做。但是,添加可选字段仍然与您描述的数据兼容,并且此表单允许您检查!==未定义的
,将处理错误案例。
type Result = Done | Error; // a disjoint union type with two cases
type Done = {| count: number |}
type Error = {| message: string |}
const doSomethingWithDone = (obj: Done) => {/*...*/}
const doSomethingWithError = (obj: Error) => {/*...*/}
const f = (result: Result) => {
if (result.count) {
doSomethingWithDone(result)
} else if (result.message) {
doSomethingWithError(result)
}
}
// Expected error. Since Error is an exact type, the count property is not allowed
const x: Error = {message: 'foo', count: 'bar'};
f(x);