流程:形状类型和其他可选字段
Flow: shape types and additional optional fields
我经常发现自己需要做以下事情,而 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]
Flow 默认对象类型不准确;这意味着,尽管 Foo
仅被声明为显式具有单个(可选)属性 foo
类型 number
,但理论上 Foo
类型的变量可以有额外的属性。例如,Foo
类型的变量可能有 属性 bar
。而且,由于 bar
未键入 Foo
,因此 bar
的类型不受限制(即不一定是 number
)。因此,如果您要与 process
中的 arg.bar
进行交互,并且 Flow 允许 arg
属于 Foo
类型,则无法保证您会与 number
。因此,流抱怨。
解决这个问题的一种方法是使用精确的对象类型。如果 Flow 知道类型 Foo
的变量永远不会有 bar
属性,那么它可以安全地传递到 process
。因此,您可以将 Foo
输入为:
type Foo = {|
+foo?: number,
|};
(注意:$ReadOnly
实用程序类型对于上面的 Foo
定义和 FooBar
的原始定义不是必需的,因为 bar
是不可写的。虽然,当然,保持 $ReadOnly
没问题。)
我经常发现自己需要做以下事情,而 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]
Flow 默认对象类型不准确;这意味着,尽管 Foo
仅被声明为显式具有单个(可选)属性 foo
类型 number
,但理论上 Foo
类型的变量可以有额外的属性。例如,Foo
类型的变量可能有 属性 bar
。而且,由于 bar
未键入 Foo
,因此 bar
的类型不受限制(即不一定是 number
)。因此,如果您要与 process
中的 arg.bar
进行交互,并且 Flow 允许 arg
属于 Foo
类型,则无法保证您会与 number
。因此,流抱怨。
解决这个问题的一种方法是使用精确的对象类型。如果 Flow 知道类型 Foo
的变量永远不会有 bar
属性,那么它可以安全地传递到 process
。因此,您可以将 Foo
输入为:
type Foo = {|
+foo?: number,
|};
(注意:$ReadOnly
实用程序类型对于上面的 Foo
定义和 FooBar
的原始定义不是必需的,因为 bar
是不可写的。虽然,当然,保持 $ReadOnly
没问题。)