编辑:由于这似乎是一个bug,我在Github #4997上打开了一个问题
在下面的示例中,流似乎假设label是mixed类型,尽管道具声明和匿名函数声明都将其绑定到Node。我遗漏了什么?
/* @flow */
import React from 'react';
import type { Node } from 'react';
type Props = {
values: { [string]: Node },
/* … */
};
export default class SelectButtons extends React.Component<Props> {
/* … */
createButtons(): Array<Node> {
return Object.entries(this.props.values).map(
([value: string, label: Node], index: number): Node => (
<button>
{label}
</button>
),
);
}
}这是错误消息:
v------
44: <button
45: onClick={() => this.choose(value)}
46: key={index}
47: className={this.block('option', { selected: value === this.state.value })()}
48: >
^ React element `button`
v------
44: <button
45: onClick={() => this.choose(value)}
46: key={index}
47: className={this.block('option', { selected: value === this.state.value })()}
48: >
^ React element `button`. This type is incompatible with
v
170: props: {
171: children?: React$Node,
172: [key: string]: any,
173: },
^ object type. See lib: /tmp/flow/flowlib_3bead812/react-dom.js:170
Property `children` is incompatible:
49: {label}
^^^^^ mixed. This type is incompatible with
171: children?: React$Node,
^^^^^^^^^^ union: undefined | null | boolean | number | string | type application of type `React$Element` | type application of identifier `Iterable`. See lib: /tmp/flow/flowlib_3bead812/react-dom.js:171
Member 1:
15: | void
^^^^ undefined. See lib: /tmp/flow/flowlib_3bead812/react.js:15
Error:
49: {label}
^^^^^ mixed. This type is incompatible with
15: | void
^^^^ undefined. See lib: /tmp/flow/flowlib_3bead812/react.js:15
Member 2:
16: | null
^^^^ null. See lib: /tmp/flow/flowlib_3bead812/react.js:16
Error:
49: {label}
^^^^^ mixed. This type is incompatible with
16: | null
^^^^ null. See lib: /tmp/flow/flowlib_3bead812/react.js:16
Member 3:
17: | boolean
^^^^^^^ boolean. See lib: /tmp/flow/flowlib_3bead812/react.js:17
Error:
49: {label}
^^^^^ mixed. This type is incompatible with
17: | boolean
^^^^^^^ boolean. See lib: /tmp/flow/flowlib_3bead812/react.js:17
Member 4:
18: | number
^^^^^^ number. See lib: /tmp/flow/flowlib_3bead812/react.js:18
Error:
49: {label}
^^^^^ mixed. This type is incompatible with
18: | number
^^^^^^ number. See lib: /tmp/flow/flowlib_3bead812/react.js:18
Member 5:
19: | string
^^^^^^ string. See lib: /tmp/flow/flowlib_3bead812/react.js:19
Error:
49: {label}
^^^^^ mixed. This type is incompatible with
19: | string
^^^^^^ string. See lib: /tmp/flow/flowlib_3bead812/react.js:19
Member 6:
20: | React$Element<any>
^^^^^^^^^^^^^^^^^^ type application of type `React$Element`. See lib: /tmp/flow/flowlib_3bead812/react.js:20
Error:
49: {label}
^^^^^ mixed. Inexact type is incompatible with exact type
20: | React$Element<any>
^^^^^^^^^^^^^^^^^^ exact type: object type. See lib: /tmp/flow/flowlib_3bead812/react.js:20
Member 7:
21: | Iterable<React$Node>;
^^^^^^^^^^^^^^^^^^^^ type application of identifier `Iterable`. See lib: /tmp/flow/flowlib_3bead812/react.js:21
Error:
49: {label}
^^^^^ mixed. This type is incompatible with
21: | Iterable<React$Node>;
^^^^^^^^^^^^^^^^^^^^ $Iterable. See lib: /tmp/flow/flowlib_3bead812/react.js:21
Property `@@iterator` is incompatible:
21: | Iterable<React$Node>;
^^^^^^^^^^^^^^^^^^^^ property `@@iterator` of $Iterable. Property not found in. See lib: /tmp/flow/flowlib_3bead812/react.js:21
49: {label}
^^^^^ mixed发布于 2017-09-29 18:06:11
现在,我假设这是个bug。如果你认为我错了,并有一个更好的答案,请随时回答,我会欣然接受它!
我认为这是一个bug,因为有以下解决办法:
createButtons(): Array<Node> {
return Object.keys(this.props.values).map((value: string, index: number): Node => (
<button>
{this.props.values[value]}
</button>
));
}通过直接引用对象,而不是使用Object.entries迭代对象,flow现在采用正确的类型。
编辑:正如我仔细考虑过的那样,问题在于数组的类型,以及流中的数组只能为它们的元素携带一种类型。
Object.entries()的回调参数为Array<mixed> => void类型。它的理想类型是Array<[K, V]> => void,其中K和V分别是对象的键类型和值类型(我认为K总是string )。
这将需要异构集合,其中Array<[K, V]>由所有长度-2数组组成,其第一个元素为K类型,第二个为V类型。这可能需要一些类型级别的操作符和更高类型的流(当前)无法提供。
使用Object.keys的解决办法是有效的,因为Object.keys不需要异构数组(所有键都是同一类型的),但是如果对象看起来不像{ [string]: X },而是具有不同类型的值(例如{ foo: number, bar: string },使其成为异构集合(再次),则可能会失败。
https://stackoverflow.com/questions/46492572
复制相似问题