I found this bug when using React, but have created a minimum example on https://flow.org/try that doesn't involve React at all
Essentially, Flow treats an instance property method differently to a prototype method. This seems to occur only when generics are involved.
I'm not sure exactly what's happening, but it's almost like different generics by the same name are used inside the instance property-based method.
The reproducing code (you can also see in the link above) is:
class Test<G> {
items: Array<G>;
protoIteratorCallback: (G) => void;
constructor(items: Array<G>) {
this.items = items;
this.protoIteratorCallback = this.protoIteratorCallback.bind(this);
}
instanceIteratorCallback = (item: G) => {}
protoIteratorCallback(item: G) {}
doSomething() {
this.items.map(this.protoIteratorCallback)
// next line fails. says `G` is not compatible with `G`
this.items.map(this.instanceIteratorCallback)
}
}
I feel like this code shouldn't be too out of the ordinary, and I can't figure out why it won't work if not for a bug.
Edit: My co-worker has just pointed out that it's broken with static properties as well. You can see the flow/try here.
class Test<G> {
items: Array<G>;
static propertyCallback = (item: G) => {}
static methodCallback(item: G) {}
doSomething() {
this.items.map(Test.propertyCallback) // fails
this.items.map(Test.methodCallback) // passes
}
}
interesting. is there a known reason why they don't work?
Most helpful comment
Here are workarounds: Try Flow, Try Flow.