Я думаю, вы можете принять массив из InternalSquare
или SquareState
:
( Попробуйте )
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>
). Это может быть даже PR-достойно.
Интересно, что расширение массива позволяет потоку понимать тип как Array<InternalSquare | SquareState>
:
( Попробуйте )
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);
}
Я бы рискнул предположить, что он на самом деле оценивает каждую из возможностей в этом случае и находит, что обе возможности работают. Общая спекуляция, хотя.