title: Typing React Context with Flow
body: <p>We're using Flow in our project and I'm chasing my tail on this one. Am using React Context to store a user's favourite assets, this will be used in multiple places. I can't get Flow happy with React Context whose <code>value</code> is an object as follows:</p>
  <pre><code>// this is the problem line!! currently having to $FlowIgnore it
  export const FavoriteAssetsContext = React.createContext(undefined);
  
  // this is all fine
  export function FavoriteAssetsProvider({
    children,
  }: FavoriteAssetsProviderProps): React.Node {
    const [favoriteAssets, setFavoriteAssets] = useState([]);
    const [favoriteAssetIds, setFavoriteAssetIds] = useState([]);
  
    const _isFavorite = (asset: Asset): boolean =&gt; { // private func };
  
    const addFavorite = useCallback((asset: Asset): void =&gt; {
      //  exported function - performs setState, no return value
    });
  
    const removeFavorite = useCallback((asset: Asset): void =&gt; {
      //  exported function - performs setState, no return value
    });
  
    return (
      &lt;FavoriteAssetsContext.Provider
        value={{ favoriteAssets, favoriteAssetIds, addFavorite, removeFavorite }}
      &gt;
        {children}
      &lt;/FavoriteAssetsContext.Provider&gt;
    );
  }
  </code></pre>
  <p>So the consumers of the context can access four properties on the <code>value</code> object. Flow is complaining about the lack of typing of the <code>FavoriteAssetsContext</code> which we export.</p>
  <p>Per the Flow <a href="https://flow.org/en/docs/react/context/" rel="nofollow noreferrer">docs</a> I've tried this:</p>
  <pre><code>type FavoriteAssetsContextType = {
      favoriteAssets: Array&lt;Asset&gt;,
      favoriteAssetIds: Array&lt;string&gt;,
      addFavorite: (asset: Asset) =&gt; void,
      removeFavorite: (asset: Asset) =&gt; void,
  };
  
  export const FavoriteAssetsContext = React.createContext&lt;FavoriteAssetsContextType&gt;({});
  </code></pre>
  <p>but I get the following error:</p>
  <blockquote>
  <p>Cannot build a typed interface for this module. You should annotate the exports of this module with types. Cannot determine the type of this call expression. Please provide an annotation, e.g., by adding a type cast around this expression. [signature-verification-failure]</p>
  </blockquote>
  <p>I have tried several permutations and combinations of <a href="https://flow.org/en/docs/types/casting/" rel="nofollow noreferrer">type casting</a> per Flow docs, which all look horribly wrong. It's complaining about the right hand side so I tried the following syntax:</p>
  <pre><code>// without generic - shouldn't be needed right?
  export const FavoriteAssetsContext = (React.createContext({}) : FavoriteAssetsContextType);
  // and with generic - ???
  export const FavoriteAssetsContext = (React.createContext&lt;FavoriteAssetsContextType&gt;({}) : FavoriteAssetsContextType);
  </code></pre>
  <p>but both times I get</p>
  <blockquote>
  <p>Cannot cast React.createContext&lt;...&gt;(...) to FavoriteAssetsContextType because property removeFavorite is missing in React.Context [1] but exists in FavoriteAssetsContextType [2]. [prop-missing]</p>
  </blockquote>
  <p>The docs have simple examples whereby the <code>value</code> is a simple string and an extensive search hasn't come up with anything examples where <code>value</code> is an object. Any help much appreciated!</p>