代码之家  ›  专栏  ›  技术社区  ›  Aleksandar Dimitrov

在对象上迭代时,流似乎采用了错误的类型。条目

  •  1
  • Aleksandar Dimitrov  · 技术社区  · 7 年前

    编辑:由于这似乎是一个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
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Aleksandar Dimitrov    7 年前

    现在,我假设这是一个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的数组占据 第二种类型 五、 . 这可能需要一些类型级别的运算符和Flow(当前)无法提供的更高类型。

    Object.keys 有效,因为 对象钥匙 { [string]: X } { foo: number, bar: string }