我经常发现自己需要执行以下操作,而Flow使其变得异常困难:
/* @flow */
type Foo = {
+foo?: number,
}
type FooBar = {
+foo?: number,
+bar?: number,
}
const foo: Foo = {foo: 2}
function process(arg: $ReadOnly<FooBar>) {
}
process(foo)
有什么好办法吗?我收到以下错误:
17: process(foo)
^ Cannot call `process` with `foo` bound to `arg` because property `bar` is missing in `Foo` [1] but exists in `FooBar` [2].
References:
12: const foo: Foo = {foo: 2}
^ [1]
14: function process(arg: $ReadOnly<FooBar>) {
^ [2]
答案 0 :(得分:1)
流默认为对象类型不精确;这意味着,尽管Foo
仅声明为显式具有类型foo
的单个(可选)属性number
,但类型Foo
的变量在理论上可以具有其他属性。例如,类型Foo
的变量可以具有属性bar
。并且,由于未在bar
中键入Foo
,因此bar
的类型不受限制(即不一定是number
)。结果,如果您要与arg.bar
中的process
进行交互,并且Flow允许arg
的类型为Foo
,则不能保证与{{ 1}}。因此,Flow抱怨了。
解决此问题的一种方法是使用精确的对象类型。如果Flow知道类型number
的变量永远不会具有Foo
属性,则可以安全地将其传递到bar
中。因此,您可以将process
输入为:
Foo
(注意:上面的type Foo = {|
+foo?: number,
|};
定义和$ReadOnly
的原始定义中,Foo
实用程序类型不是必需的,因为FooBar
是不可写的。 ,可以保留bar
。)