Closed Gallinaryoso closed 1 year ago
I agree that something is not right. It works if you explicitly cast union to $ReadOnlyArray
:
function fun(arr: Array<string> | Array<number>): number {
const thisDoesNotWork = (arr: $ReadOnlyArray<string|number>).slice(-1);
return 0;
}
Isn't this expected behavior because of variance? Any value you pass in would only be a subtype of the input type. And because slice
returns a T
from Array<T>
, it has to pick a T
, which would mean the value is being cast to one vase or the other rather than treated as the original union type.
This is not the expected behavior. Array.slice
only works if you cast the union type immediately before slice
: https://flow.org/try/#0C4TwDgpgBAqgdgSwPZwCrmgXigQQE54CGIAPAM7B4JwDmAfFAD64HElwCuAtgEYR50A3AChhAMw5wAxsGRwoAEyQQyAOSTAA6kjwBrABSECALhZFSFKrQbN859tz4CAlKc69+UAN7CoUKSgUUMAAFghkACLKahraelDYRngAdGQANghSEPoAtACMziJ+eBDAHHjyAAwiAL6iEtKyKFCEaWRIUSrqWjoGSabwcuiQrlDuTt6+-oHAwWFkOG0d0d1xuglQhiawiCjDEM6pGVm5BUVQJWUVUNXCdeKSMnJQAO69ZABi1Nn9ZmyW1HoTD+pHG-DoozBeEmfgCcCCoXCnTIaw2Wzwpjs-0ogJsIIcHhcR0y2XyhSml3KVVqwiAA
All of these functions are doing the same thing. Why do the first two not work, yet the last does.
This now works.
https://flow.org/try/#0FAMwrgdgxgLglgewgAnBAFAQwE7YFzICCumAngDwDOM2cEA5gHzIA+RJFEYAtgEYCm2RgEoCXPoOQBvYMmRQk1ZDAAWcSgBEE-SgDkEMAOoJsAa2QBeZDmwA6SgBs4UfugC0ARmEBuWcmz8MGDYKAAMvgC+wEA flow seems to be determining that arr.slice(-1) is necessarily an array of strings, which is not the case.