在下面的代码块中,仅当getInnerValues
函数存在时,OuterY
和OuterZ
类型定义上才会发生流错误。
这些错误抱怨"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);