Skip to content

Instantly share code, notes, and snippets.

@amccloud
Last active June 14, 2019 03:45
Show Gist options
  • Save amccloud/3e421944f82c8b6a2e11e45c1aae0314 to your computer and use it in GitHub Desktop.
Save amccloud/3e421944f82c8b6a2e11e45c1aae0314 to your computer and use it in GitHub Desktop.

Common Flow Issues

Below are a list of common flow issues with a brief explanations of the problem and possible solutions. The dynamic parts of the error message have all been replaced with a wildcard character * in the error message to aid with finding it on this page

Cannot resolve module *

// $FlowError: Cannot resolve module *
import example from "example";

Problem

Flow is not aware of the module "example"

Solutions

  • Install flow-typed module yarn flow-typed install example
  • Or create a stub module with yarn flow-typed create-stub example
  • Or blacklist module in your projects .flowconfig. Not ideal but sometimes required when vendors ship their own invalid types

Missing type annotation for *. * is a type parameter declared in array type [1] and was implicitly instantiated at call of method * [2]

export function test() {
  // $FlowError: Missing type annotation for *. * is a type parameter declared in array type [1] and was implicitly instantiated at call of method * [2]
  return [].map(a => a);
}

Problem

Flow does not know your Array.map or filter call won't change the type of the array

Solutions

  • Provide return type annotation for the result of your map or filter call
export function test(): Array<{}> {
  return [].map(a => a);
}

Missing type annotation for *

// $FlowError Missing type annotation for *. * is a type parameter declared in function type [1] and was implicitly instantiated at call of * [2].
export default connect(mapStateToProps, mapDispatchToProps);

Problem

Flow 0.85 introduced stricter requirements for annotating exported functions. Functions with generic parameters like connect, createSelector and defineRequest require annotation if the return value is exported. Not all parameters are require annotation. Optional paramters can be omitted with _, but providing all paramerters is recommended because it usually leads to better error messages

Solution

  • Provide required annotations

connect

export default connect<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(mapStateToProps, mapDispatchToProps);

connect with no dispatch

export default connect<Props, OwnProps, StateProps, _, State, Dispatch>(mapStateToProps);

connect with no state

export default connect<Props, OwnProps, _, DispatchProps, State, Dispatch>(undefined, mapDispatchToProps);

createSelector / createCachedSelector

// TBA

defineRequest

export default defineRequest<PerformParams, IdParams>({/* ... */});

Missing type annotation for call of compose

// $FlowError: Missing type annotation for call of compose.
export default compose(
  connect<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(
    mapStateToProps,
    mapDispatchToProps
  ),
  withData(makeInput)
);

Problem

Same problem as above. See: Missing type annotation for *

Solution

  • Export annotated compose using a variable or helper liker createConnector
const connector: (React.AbstractComponent<Props>) => React.AbstractComponent<OwnProps> = compose(
  connect<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(
    mapStateToProps,
    mapDispatchToProps
  ),
  withData(makeInput)
);

Or more succinctly with a helper around compose called createConnector for convention:

export default createConnector<Props, OwnProps>(
  connect<Props, OwnProps, StateProps, DispatchProps, State, Dispatch>(
    mapStateToProps,
    mapDispatchToProps
  ),
  withData(makeInput)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment