Search code examples
javascriptflowtypetypechecking

Why does Flow assume this function returns a RegExp?


I have the following code: a function which returns an option from an array. The options could be strings or regexes, and the return value will follow suit.

const pick = (options: Array<string | RegExp>): string | RegExp =>
  options[Math.floor(Math.random() * options.length)];

const myOptions = ['hello', 'goodbye']
const randomId: string = pick(myOptions);

This raises this error:

Cannot assign pick(...) to randomId because RegExp [1] is incompatible with string [2].Flow(incompatible-type)

Why is this?


Solution

  • Ok, building from the comments, there are several issues here:

    • the type signature of the array is "Array of things that are either strings or regexs", not "Array of strings or array of regexes"
    • Flow doesn't know that the return type matches the provided type, so it's possible the function returns a regex, which can't be stored in a string.

    Using a generic, we can redefine the function like this:

    const pick = <T>(options: Array<T>): T =>
      options[Math.floor(Math.random() * options.length)];
    

    This works fine.