首页 > 解决方案 > 带有联合参数的函数间接导致联合成员出现莫名其妙的错误

问题描述

在下面的代码块中,流错误在函数存在时发生在OuterYOuterZ类型定义上。getInnerValues

这些错误抱怨"Y"并且"Z""X". 例如:“字符串文字Y与字符串文字不兼容X。” .

/* @flow */

type Inner<T> = { value: T };

type OuterX = { inner: Array<Inner<"X">> };
type OuterY = { inner: Array<Inner<"Y">> };
type OuterZ = { inner: Array<Inner<"Z">> };

type Outer = OuterX | OuterY | OuterZ;

// If the next line is present, errors occur on
// lines 6 and 7 complaining that "Y" and "Z" are
// incompatible with "X". When the next line is
// commented out, the errors go away. Why??
const getInnerValues = (outer: Outer) => outer.inner.map(inner => inner.value);

为什么会这样?

单击此处在flow.org/try上查看问题

单击此处查看在flow.org/try上更严格输入的相同问题

标签: flowtype

解决方案


Flow 没有意识到对于所有可能的情况都存在inner类型属性。解决此问题的一种方法是键入函数以接受具有预期类型的​​对象:{value: string}Outer

试试

/* @flow */

type Inner<T> = { value: T };

type OuterX = { inner: Array<Inner<"X">> };
type OuterY = { inner: Array<Inner<"Y">> };
type OuterZ = { inner: Array<Inner<"Z">> };

type Outer = OuterX | OuterY | OuterZ;

// no errors
const getInnerValues = (outer: {inner: Array<{value: string}>}) =>
    outer.inner.map(inner => inner.value);

另一种方法(可能是更好的方法)是重新定义Outer为接受类型参数的类型。然后,您可以通用地键入您的getInnerValues函数以接受通用Outer实例:

试试

/* @flow */

type Inner<T> = { value: T };

type OuterX = { inner: Array<Inner<"X">> };
type OuterY = { inner: Array<Inner<"Y">> };
type OuterZ = { inner: Array<Inner<"Z">> };

type Outer<T> = {
  inner: Array<Inner<T>>               
}

// no errors
const getInnerValues = <T>(outer: Outer<T>) => outer.inner.map(inner => inner.value);

推荐阅读