Flow: Unable to detect divergent polymorphic types

Created on 15 Aug 2016  路  6Comments  路  Source: facebook/flow

I'm not sure if this a bug or if I just haven't uncovered the documentation on how to do this, but I want to be able to have a function that takes two functions as parameters, and have flow enforce that the two functions return the same type. However, both locally and in the "try flow" editor, the following code yields no errors, even though one function is returning a string and the other returns a number:

function test<A>(a: () => A, b: (num: number) => A): A {
  if (Math.random() == 0)
    return a()
   else {
     return b(1)
   }
}

test(() => 'a', (num: number) => 1)

Any help would be much appreciated! :smile:

Needs docs polymorphism

All 6 comments

Flow infers that A is string | number in this case. Not sure that there is some simple way around this.

Darn, that's too bad. Do you know if there's some way to hint what A should be? Like something like:

test<string>(() => 'a', (num: number) => 1)

In your case probably var a: string = test(() => 'a', (num: number) => 1) is the easiest way

Ah ok. I would have hoped that this could be detected automatically, but I guess that's difficult because of union types. Thanks for your help!

@msiebert Thanks for the excellent example! This points to a limitation of subtyping-based inference, which often under-constrains the system until a real error is found (which is why the return type casting of @vkurchatkin causes an expected error). Good to keep this example in mind for docs and future work!

This is a good example for Union Types in polymorphism, should docs this to Union Types?
@avikchaudhuri Hope do not remove this feature, its a powerful mechanism to collect type information.

Was this page helpful?
0 / 5 - 0 ratings