Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无标记的不相交并集_Javascript_Flowtype - Fatal编程技术网

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);