我有以下flow
代码(available here):
type SquareState = {
value: number,
};
type InternalSquare = {
value: number | null,
};
export function getMax(squares: Array<InternalSquare> | Array<SquareState>): number {
return squares.reduce(function(a : number, b : InternalSquare | SquareState): number {
if (b.value === null) {
return a;
} else {
return Math.max(a, b.value);
}
}, 0);
}
产生此错误:
9: export function getMax(squares: Array<InternalSquare> | Array<SquareState>): number {
^ number [1] is incompatible with null [2] in property `value`.
References:
2: value: number,
^ [1]
6: value: number | null,
^ [2]
据我了解,应该没有错误,因为有防范null
。代码可以正常使用:
export function getMax(squares: Array<SquareState>): number
或
export function getMax(squares: Array<InternalSquare>): number
但不是Array<SquareState> | Array<InternalSquare>
此外,如果我replace the reduce with a for loop,它可以运作:
export function getMax(squares: Array<InternalSquare> | Array<SquareState>): number {
var max = 0;
for(var i = 0 ; i < squares.length ; i ++) {
if (squares[i].value === null) {
continue;
} else {
max = Math.max(max, squares[i].value);
}
}
return max;
}
我错过了什么?
答案 0 :(得分:2)
我想你可能想要接受InternalSquare
或SquareState
的数组:
(Try)
type SquareState = {
value: number,
};
type InternalSquare = {
value: number | null,
};
export function getMax(squares: Array<InternalSquare | SquareState>): number {
return squares.reduce(function(a : number, b : InternalSquare | SquareState): number {
if (b.value === null) {
return a;
} else {
return Math.max(a, b.value);
}
}, 0);
}
似乎流不会意识到减少两个数组(Array<A> | Array<B>
)的并集等同于减少两种类型的并集数组(Array<A | B>
)。这甚至可能是有价值的。
有趣的是,传播数组允许流程将类型理解为Array<InternalSquare | SquareState>
:
(Try)
type SquareState = {
value: number,
};
type InternalSquare = {
value: number | null,
};
export function getMax(squares: Array<InternalSquare> | Array<SquareState>): number {
const afterSpread = [...squares]
return afterSpread.reduce(function(a : number, b : InternalSquare | SquareState): number {
if (b.value === null) {
return a;
} else {
return Math.max(a, b.value);
}
}, 0);
}
更有趣的是,如果您将其中一个数组(但不是两个!)更改为$ ReadOnlyArray,它也会理解这里发生了什么:
type SquareState = {
value: number,
};
type InternalSquare = {
value: number | null,
};
export function getMax(squares: $ReadOnlyArray<InternalSquare> | Array<SquareState>): number {
return squares.reduce(function(a : number, b : InternalSquare | SquareState): number {
if (b.value === null) {
return a;
} else {
return Math.max(a, b.value);
}
}, 0);
}
我猜测它实际上是在评估这种情况下的每种可能性,并发现两种可能性都有效。但总的猜测。