流动中的脱节联盟不是"脱节"

时间:2018-01-05 01:15:23

标签: javascript flowtype

我在尝试使用" disjoint unions"时遇到了一些问题。由flow创建。显然流量试图将它们混合在一起,但我仍然不知道为什么。

type Single = {|
  type: 'single',
  value?: string,
  onChange: (value?: string) => void,            // line:47
|};

type Multiple = {|
  type: 'multiple',
  value?: string[],
  onChange: (value: string[]) => void,           // line:53
|}
type Props = Single | Multiple;

拥有上面的流程定义,我应该能够毫无错误地执行此操作,对吗?

// (Yes, it is react)
function someFunc(receivedValues?: string[]) {
  // ...
  // value, type and onChange were pulled from "props: Props"

    if (type === 'single') {
      if (receivedValues && receivedValues.length) {
        onChange(receivedValues[0]);                     // line:110
      }
    } else if (type === 'multiple') {
      if (receivedValues && receivedValues.length) {
        const casted: string[] = value && value.length ? value : [];
        onChange(casted.concat(receivedValues));         // line:115
      }
    }

  //...
}

但是流程引发了我多次错误:

Error: file.jsx:110
110:   onChange(receivedValues[0]);
                ^^^^^^^^^^^^^^^ string. This type is incompatible with the expected param type of
 53:   onChange: (value: string[]) => void,
                         ^^^^^^^^ array type

Error: file.jsx:114
114:   const casted: string[] = value && value.length ? value : [];
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string. This type is incompatible with
114:   const casted: string[] = value && value.length ? value : [];
                     ^^^^^^^^^^ array type

Error: file.jsx:115
115:   onChange(casted.concat(receivedValues));
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ array type. This type is incompatible with the expected param type of
 47:   onChange: (value?: string) => void,
                          ^^^^^^^ string

根据我的理解,它只是合并SingleMultiple,而不是选择其中之一。有没有人知道如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

由于您已经从对象中提取了值,因此检查type对缩小valueonChange的类型没有影响。如果您直接使用该对象,您的代码将起作用:

function someFunc(receivedValues?: string[]) {
  var obj: Props = { type: 'single', onChange: () => {} };

  if (obj.type === 'single') {
    if (receivedValues && receivedValues.length) {
      obj.onChange(receivedValues[0]);
    }
  } else if (obj.type === 'multiple') {
    if (receivedValues && receivedValues.length) {
      const casted: string[] = obj.value && obj.value.length ? obj.value : [];
      obj.onChange(casted.concat(receivedValues));
    }
  }
}

On Flow playground

或仅在细化类型后从对象中解构出值。

function someFunc(receivedValues?: string[]) {
  var obj: Props = { type: 'single', onChange: () => {} };

  if (obj.type === 'single') {
    const { onChange } = obj;
    if (receivedValues && receivedValues.length) {
      onChange(receivedValues[0]);
    }
  } else if (obj.type === 'multiple') {
    const { onChange, value } = obj;
    if (receivedValues && receivedValues.length) {
      const casted: string[] = value && value.length ? value : [];
      onChange(casted.concat(receivedValues));
    }
  }
}

On Flow playground