profile
viewpoint

Ask questionsReact: Flow cannot infer generic type of HOC

Flow version: v0.121.0 (and earlier versions)

UPDATE: I've reduced the repro case and title from the original post following Jack's first comment below.

When using HOCs in React, I'm struggling to get flow to infer generic types. Take for instance this case where I'm using the "trivialHOC" example from the docs:

import React, { type AbstractComponent } from 'react';

function trivialHOC<Config>(Component: AbstractComponent<Config>): AbstractComponent<Config> {
  return Component;
}

const DemoComponent = () => <div />;

const WrappedDemoComponent = trivialHOC(DemoComponent);

Error is on the call to trivialHOC(DemoComponent):

Missing type annotation for `Config`. `Config` is a type parameter declared in  function [1] and was implicitly instantiated at  call of `trivialHOC` [2].

I'm not sure if it's a red herring, but I noticed that this error only repros when I export the wrapped component (export default WrappedDemoComponent;). Otherwise flow seems happy with it.

Expected behavior:

Flow should be able to infer the type of the component as it's passed into trivialHOC and it should correctly return a component of type AbstractComponent<Config>.

Actual behavior

Flow cannot infer the inbound type and therefore complains that no generic type has been provided.

  • Link to Try-Flow or Github repo: https://flow.org/try/#0PTAEAEDMBsHsHcBQBLAtgB1gJwC6gEoCmAhgMY4A0oA3qDgJ7qGgCCARgM45Zk4DCsDLAB2hYXgC+oSFkGgA5FhLl5AbkSJIAV2HlkIulmQA3ZMWgAJAPJ8APAOGRkAcwB8ACgFDR4gFytObl4vTB8cexEnNwBKf3YuHnIQkTFwhyjXGkRQUCUcLSxhUGSw9QkNUhEuUAARQlRYEtTQAF5Qd2jWzNsAExNQYFd1RErhaoB1HnQmHrqGpvFWwxMzSxt3OcbBUNTo4ZBQABUAC2ZCLFksUD6OYmmSLA5QZEhQelgtUErUVGaPvBwx2QT1EAA88NBkKJfIhCKDMLhroRIMQtNA8JM7jNNgscOogA
facebook/flow

Answer questions dsainati1

This has to do with the variance of these generics (https://flow.org/en/docs/lang/variance/). The Config generic appears contravariantly in the definition of AbstractComponent, and thus contravariantly in the return type of your HOC. By contrast the T generic appears covariantly in the return of identity.

We specifically do not allow you to export inferred contravariant positions, because it becomes impossible to know how much the type will widen when used in different files. Notice that the error disappears if you don't try to export fooA.

useful!

Related questions

Common spread pattern leads to "exponentially large number of cases" errors hot 1
Flow issue "Please upgrade flow to version >=0.75." hot 1
Object.fromEntries type defs missing hot 1
Cannot set defaultProps with React.memo and React.forwardRef hot 1
Inexact rest object claims it may have properties it can't possibly have hot 1
Inexact rest object claims it may have properties it can't possibly have hot 1
Inexact rest object claims it may have properties it can't possibly have hot 1
0.92.0 release crashes on startup (Unix.Unix_error) hot 1
module.name_mapper does not find nested modules on windows hot 1
Cannot import useState because there is no useState export in react. hot 1
Can't use a default value from a destructuring assignment as a computed property since 0.111 hot 1
Flow issue "Please upgrade flow to version >=0.75." hot 1
Allow explicitly including a folder under an ignored path hot 1
Flow caches and fails to purge errors hot 1
Version `0.105.0` is missing the binaries hot 1
Github User Rank List