Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow union of function types

I'm working on adding flow types to a JS codebase and have run into some untyped code like this:

const doSomething = (callback, type) => {
    if (type === 'one') {
        const bool = callback(42)
    } else if (type === 'two') {
        const str = callback(4, 2)
    }
}

The function takes a callback that has one of two signatures, and a type argument which is a string that indicates which signature the callback uses.

In my first attempt to add flow, I've ended up with the following:

/* @flow */

type Callback1 = (any) => bool
type Callback2 = (any, any) => string

type WhichFunc = 'one' | 'two'
type Func = Callback1 | Callback2

const test = (func: Func, which: WhichFunc) => {
  if (which === 'one') {
    const b: bool = func(42)
  } else if (which === 'two') {
    const s: string = func(4, 2)
  }
}

This fails, unsurprisingly, because flow has no way to verify that the which string has any relation to func.

Is there a way to add flow types here without changing the API?

like image 261
zmb Avatar asked Jul 09 '26 22:07

zmb


1 Answers

You can make an explicit (but cumbersome) typecast like this:

const test = (func: Func, which: WhichFunc) => {
  if (which === 'one') {
    const callback: Callback1 = ((func: any): Callback1);
    const b: bool = callback(42);
  } else if (which === 'two') {
    const callback: Callback2 = ((func: any): Callback2);
    const s: string = callback(4, 2)
  }
};

You can also see this on flow.org/try 🙂

like image 57
MichaelDeBoey Avatar answered Jul 11 '26 13:07

MichaelDeBoey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!