带有联合参数的函数间接导致工会成员出现莫名其妙的错误



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

这些错误抱怨"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上更严格输入的相同问题

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

(尝试(

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

最新更新