-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maybe union type ordering error #5320
Comments
Hey @deanbrophy this is because Therefore you always want to order your types from most specific to least so it doesn't match an unwanted type. |
@bradennapier Excellent! That makes sense. I'm wondering if the error message could be more specific, though, or is this something that's explicit in the documentation? |
Actually upon reading this error it is actually different from what I assumed:
Basically it is saying that it is epxecting the Indicating that we will be passing a non-array type in the annotation seems to fix this. Try Flow/* @flow */
type $NonArrayType<A> = $Call<(<T>(Array<T> | T) => T), A>
function forEachAccumulated<T>(
arr: ?(T | Array<T>),
cb: (elem: $NonArrayType<T>) => void,
scope: ?any,
) {
if (Array.isArray(arr)) {
arr.forEach(cb, scope);
} else if (arr) {
cb.call(scope, arr);
}
}
type Whatever = {
Stuff: number
}
var myList: ?(Whatever | Array<Whatever>) = null;
function doStuff(){
forEachAccumulated(myList, doThis);
}
// Without $NonArrayType<T> this function is expecting
// { Stuff: number } | Array<{ Stuff: number }>
// -- but you had specifically annotated it to be
// { Stuff: number } - so it did not type properly.
function doThis(something: Whatever) {
// $Works
(something: { Stuff: number });
// $ExpectError
//(something: [{ Stuff: 1 }, { Stuff: 2 }]);
} This should provide the perfect illustration of why your example provided an error: Try Flow// this is what you were giving the function but had it annotated as `Whatever`
function doThis(something: Whatever | Array<Whatever>){} Yes, there is no question that the errors that Flow provides are pretty hard to decipher. In many cases they show up in the wrong places and are masked by other errors or problems. I would imagine that is a very difficult thing to handle properly -- here's to hoping they continually refine such things over time ;-). |
Right on! I think it's safe to close out this issue then. Man, I need to get caught up on utility types, but they're not very well documented. I had no idea $Call existed. |
@deanbrophy you can take a look at our pubchan package. It has some useful utility types for composing your types: https://github.com/Dash-OS/pubchan/blob/master/src/pubchan/types/utils.js |
Right on. I wish the built-in Flow utility types were better documented. It looks like things like $Call have no documentation whatsoever. |
Expected Result
Maybe union types can be specified in any order:
?(Array<T> | T)
?(T | Array<T>)
Actual Result
The ordering does matter. Specifying the array first works correctly. While including the generic first causes an error.
I first noticed this error in React using flow version 0.53.1, but the examples provided above are for v0.59.0
The text was updated successfully, but these errors were encountered: