Javascript 为什么函数的交集类型接受其中一种类型声明,而不是同时接受两种类型声明?
我举了个例子Javascript 为什么函数的交集类型接受其中一种类型声明,而不是同时接受两种类型声明?,javascript,flowtype,Javascript,Flowtype,我举了个例子 /* @flow */ class Foo {} class Bar {} declare var f: ((x: Foo) => void) & ((x: Bar) => void); f(new Foo()); 从文档页面 这种代码类型检查时没有错误 对我来说,结果不是很明显 正如他们在页面顶部附近的某个地方用另一个示例所示: /* @flow */ type I = {a: number} & {b: number}; var x: I = {a
/* @flow */
class Foo {}
class Bar {}
declare var f: ((x: Foo) => void) & ((x: Bar) => void);
f(new Foo());
从文档页面
这种代码类型检查时没有错误
对我来说,结果不是很明显
正如他们在页面顶部附近的某个地方用另一个示例所示:
/* @flow */
type I = {a: number} & {b: number};
var x: I = {a: 1, b: 2};
x = {a: 1, b: 2, c: "three"};
交叉点(来自术语语义本身)是两种(或更多)类型的复合。基本上是和
那么,为什么f(newfoo())代码>是否未通过类型检查?new Foo()
参数显然不是条的实例,因此不能通过
我错过了什么
UPD
经过进一步研究,我发现当你使用声明var
(与类型
或就地键入相比,和&
的含义是互换的。我无法找到一个解释,为什么它会在一开始就发生。我可能误解了你的问题,但我希望它会进行打字检查。参数new Foo()
具有类型Foo
,因此只要f
具有类型Foo=>…
,应用程序就应该是正常的。是的。(它还有类型Bar=>…
)
作为比较,如果f
具有类型(x:Foo&Bar)=>void
,则不会进行类型检查,因为new Foo
,当然是类型Foo
,但也不是类型Bar
另一个比较是,如果f
有type((x:Foo)=>void)|((x:Bar)=>void)
,则不会进行打字检查。参数newfoo
的类型为Foo
,虽然f
可能有类型Foo=>void
,但它可能有类型Bar=>void
,,我只引用文档:“交集类型需要一个值作为所有输入类型:”。在本例中,参数不满足此条件,因为f(newfoo())代码>不是((x:Bar)=>void)
类型。另一个有争议的例子:declare var
和declare type
表现不同:嗯,我不太明白:(x:Bar)=>void
类型是用于f
本身,而不是f(new Foo())
。我们说的是f
函数既是(x:Foo)=>void
类型,也是(x:Bar)=>void
类型;因此,调用类型为Foo
的参数是可以的。在您的try-flow示例中,问题是您说过a
具有类型F=((x:Foo)=>void)和((x:Bar)=>void)
,但它没有!它只有类型(x:Foo)=>void
。但是,如果您将a
的定义更改为函数(x:Foo | Bar)
,它将再次进行打字检查。现在我明白了您的意思,但这对我来说仍然是违反直觉的:-s