facebook / flow

Adds static typing to JavaScript to improve developer productivity and code quality.
https://flow.org/
MIT License
22.08k stars 1.86k forks source link

Union of array types does not work with slice() method #4504

Closed Gallinaryoso closed 1 year ago

Gallinaryoso commented 7 years ago

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.

vkurchatkin commented 7 years 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;
}
asolove commented 7 years ago

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.

nivekmai commented 6 years ago

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.

SamChou19815 commented 1 year ago

This now works.