2017-09-29 2 views
1

EDIT Iterieren: da dies einen Fehler zu sein scheint, ich habe auf Github ein Problem geöffnet #4997Fluss scheint falsche Art zu übernehmen, während sie über Object.entries

Im folgenden Beispiel scheint Flow davon ausgehen, dass label ist vom Typ mixed, obwohl sowohl die Props-Deklaration als auch die anonyme Funktionsdeklaration an Node binden. Was vermisse ich?

/* @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> 
    ), 
    ); 
    } 
} 

Dies ist die Fehlermeldung:

   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 

Antwort

0

Gerade jetzt, ich gehe davon aus, dass es ein Fehler ist. Wenn Sie denken, dass ich falsch liege und eine bessere Antwort habe, antworten Sie bitte, und ich werde es gerne annehmen!

Ich nehme an, es ein Fehler ist, weil die folgende Abhilfe:

createButtons(): Array<Node> { 
    return Object.keys(this.props.values).map((value: string, index: number): Node => (
    <button> 
     {this.props.values[value]} 
    </button> 
)); 
} 

Durch das Objekt direkt referenzieren, anstatt über sie Laufen mit Object.entries, fließt nun davon ausgegangen, den richtigen Typen.

EDIT: Da ich dies ein wenig mehr Gedanken gemacht habe, liegt das Problem in der Eingabe von Arrays, und die Tatsache, dass Arrays in Flow nur einen Typ für ihre Elemente tragen können.

Das Callback-Argument Object.entries() ist vom Typ Array<mixed> => void. Ein idealer Typ für sie Array<[K, V]> => void wäre, wo K und V die Objekte Schlüssel und Werttypen sind jeweils (K ist immer string, glaube ich.)

Dies würde heterogene Sammlungen erfordern, wo Array<[K, V]> von der ganzen Länge bewohnt -2 Arrays, deren erstes Element vom Typ K und das zweite vom Typ V ist. Dies würde wahrscheinlich einige Operatoren auf Typenebene und höherwertige Typen erfordern, die Flow (derzeit) nicht bereitstellen kann.

Die Abhilfe Object.keys Werke zu verwenden, da Object.keys nicht heterogenen Arrays benötigt (alle Tasten des gleichen Typs sind), aber es könnte fehlschlagen, wenn Ihr Objekt wie { [string]: X } sieht nicht, sondern weist Werte verschiedenen Typen (zB { foo: number, bar: string }, so dass es (wieder) eine heterogene Sammlung ist.

Verwandte Themen