首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Object.entries上迭代时,流似乎采用了错误的类型

在Object.entries上迭代时,流似乎采用了错误的类型
EN

Stack Overflow用户
提问于 2017-09-29 15:49:48
回答 1查看 1.6K关注 0票数 1

编辑:由于这似乎是一个bug,我在Github #4997上打开了一个问题

在下面的示例中,流似乎假设labelmixed类型,尽管道具声明和匿名函数声明都将其绑定到Node。我遗漏了什么?

代码语言:javascript
复制
/* @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>
      ),
    );
  }
}

这是错误消息:

代码语言:javascript
复制
             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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-29 18:06:11

现在,我假设这是个bug。如果你认为我错了,并有一个更好的答案,请随时回答,我会欣然接受它!

我认为这是一个bug,因为有以下解决办法:

代码语言:javascript
复制
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,其中KV分别是对象的键类型和值类型(我认为K总是string )。

这将需要异构集合,其中Array<[K, V]>由所有长度-2数组组成,其第一个元素为K类型,第二个为V类型。这可能需要一些类型级别的操作符和更高类型的流(当前)无法提供。

使用Object.keys的解决办法是有效的,因为Object.keys不需要异构数组(所有键都是同一类型的),但是如果对象看起来不像{ [string]: X },而是具有不同类型的值(例如{ foo: number, bar: string },使其成为异构集合(再次),则可能会失败。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46492572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档