Flow: Flow cannot distinguish function from object

Created on 17 Jun 2019  路  4Comments  路  Source: facebook/flow

Flow version: 0.100.0

I am trying to describe the type for the function makeStyles() from @material-ui/core

And using overload to describe two cases:

  • when the first argument is a function
  • when the usual object

Expected behavior

Can be described not called object

Actual behavior

And ran into the problem that the flow cannot distinguish the function from the object:

Try link

type Theme = {
 color: {active: string}
};

type Stl = {
    [string]: {}
}

declare var make:
  & ((callback: (Theme) => Stl) => void) 
  & ((callback: Stl) => void)


make({root:{}});

make((theme) => {
  (theme.color.active: string);

  (theme.color.active: number); // expect error

  return ({root:{}});
});
unionintersections bug

All 4 comments

looks to be similar to https://github.com/facebook/flow/issues/6784 (who's author is seemingly working on material-ui flow-typed defs as well), and ultimately links to this umbrella issue https://github.com/facebook/flow/issues/6490. Is using $Shape a reasonable work-around? Is there a better suggestion?

@chasestarr hack with $Shape<> has helped

Try flow.js

Experimenting I found a strange pattern:

  • If the function returns the type $ObjMap<T, F>, we do not have "case problem".

  • But when a function returns another function witch return $ObjMap<T, F> (as in the example below) we have got an error: Could not decide which case to select, need type for "theme"

Try flow.js

type Theme = {
  color: { active: string },
};

type Style<Props, Classes> = {
  [Classes]: $Shape<{}> | (Props => $Shape<{}>),
};

type StyleHookFn<_Props, Stl> = (props?: _Props) => $ObjMap<Stl, () => string>;

declare var makeStyles: {
  <Props, Stl: Style<Props, string>>(
    callback: (Theme) => Stl
  ): StyleHookFn<Props, Stl>,
  <Props, Stl: Style<Props, string>>(styles: Stl): StyleHookFn<Props, Stl>,
};

makeStyles({ root: {} });

makeStyles(theme => { //  Error: Could not decide which case to select, need type for `theme`
  (theme.color.active: string);

  (theme.color.active: number); // expect error, check any

  return { root: {} };
});

This problem very critical for me

it's because Stl and () => Stl are considered equivalent

I made these changes to make your example pass. Most notably the $Shape around the result of Style<Props, Classes>

See this issue and related bug reports to better understand what's happening: https://github.com/facebook/flow/issues/106

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Beingbook picture Beingbook  路  3Comments

davidpelaez picture davidpelaez  路  3Comments

ghost picture ghost  路  3Comments

cubika picture cubika  路  3Comments

bennoleslie picture bennoleslie  路  3Comments