title: React with Typescript -- Generics while using React.forwardRef
body: <p>I am trying to create a generic component where a user can pass the a custom <code>OptionType</code> to the component to get type checking all the way through. This component also required a <code>React.forwardRef</code>.</p>
  
  <p>I can get it to work without a forwardRef. Any ideas? Code below:</p>
  
  <p><strong>WithoutForwardRef.tsx</strong></p>
  
  <pre><code>export interface Option&lt;OptionValueType = unknown&gt; {
    value: OptionValueType;
    label: string;
  }
  
  interface WithoutForwardRefProps&lt;OptionType&gt; {
    onChange: (option: OptionType) =&gt; void;
    options: OptionType[];
  }
  
  export const WithoutForwardRef = &lt;OptionType extends Option&gt;(
    props: WithoutForwardRefProps&lt;OptionType&gt;,
  ) =&gt; {
    const { options, onChange } = props;
    return (
      &lt;div&gt;
        {options.map((opt) =&gt; {
          return (
            &lt;div
              onClick={() =&gt; {
                onChange(opt);
              }}
            &gt;
              {opt.label}
            &lt;/div&gt;
          );
        })}
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p><strong>WithForwardRef.tsx</strong></p>
  
  <pre><code>import { Option } from './WithoutForwardRef';
  
  interface WithForwardRefProps&lt;OptionType&gt; {
    onChange: (option: OptionType) =&gt; void;
    options: OptionType[];
  }
  
  export const WithForwardRef = React.forwardRef(
    &lt;OptionType extends Option&gt;(
      props: WithForwardRefProps&lt;OptionType&gt;,
      ref?: React.Ref&lt;HTMLDivElement&gt;,
    ) =&gt; {
      const { options, onChange } = props;
      return (
        &lt;div&gt;
          {options.map((opt) =&gt; {
            return (
              &lt;div
                onClick={() =&gt; {
                  onChange(opt);
                }}
              &gt;
                {opt.label}
              &lt;/div&gt;
            );
          })}
        &lt;/div&gt;
      );
    },
  );
  </code></pre>
  
  <p><strong>App.tsx</strong></p>
  
  <pre><code>import { WithoutForwardRef, Option } from './WithoutForwardRef';
  import { WithForwardRef } from './WithForwardRef';
  
  interface CustomOption extends Option&lt;number&gt; {
    action: (value: number) =&gt; void;
  }
  
  const App: React.FC = () =&gt; {
    return (
      &lt;div&gt;
        &lt;h3&gt;Without Forward Ref&lt;/h3&gt;
        &lt;h4&gt;Basic&lt;/h4&gt;
        &lt;WithoutForwardRef
          options={[{ value: 'test', label: 'Test' }, { value: 1, label: 'Test Two' }]}
          onChange={(option) =&gt; {
            // Does type inference on the type of value in the options
            console.log('BASIC', option);
          }}
        /&gt;
        &lt;h4&gt;Custom&lt;/h4&gt;
        &lt;WithoutForwardRef&lt;CustomOption&gt;
          options={[
            {
              value: 1,
              label: 'Test',
              action: (value) =&gt; {
                console.log('ACTION', value);
              },
            },
          ]}
          onChange={(option) =&gt; {
            // Intellisense works here
            option.action(option.value);
          }}
        /&gt;
        &lt;h3&gt;With Forward Ref&lt;/h3&gt;
        &lt;h4&gt;Basic&lt;/h4&gt;
        &lt;WithForwardRef
          options={[{ value: 'test', label: 'Test' }, { value: 1, label: 'Test Two' }]}
          onChange={(option) =&gt; {
            // Does type inference on the type of value in the options
            console.log('BASIC', option);
          }}
        /&gt;
        &lt;h4&gt;Custom (WitForwardRef is not generic here)&lt;/h4&gt;
        &lt;WithForwardRef&lt;CustomOption&gt;
          options={[
            {
              value: 1,
              label: 'Test',
              action: (value) =&gt; {
                console.log('ACTION', value);
              },
            },
          ]}
          onChange={(option) =&gt; {
            // Intellisense SHOULD works here
            option.action(option.value);
          }}
        /&gt;
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p>In the <code>App.tsx</code>, it says the <code>WithForwardRef</code> component is not generic. Is there a way to achieve this?</p>
  
  <p>Example repo: <a href="https://github.com/jgodi/generics-with-forward-ref" rel="noreferrer">https://github.com/jgodi/generics-with-forward-ref</a></p>
  
  <p>Thanks!</p>