title: Passing implementations of generic types to React component props
body: <p>I'm working on a TypeScript/React project and we're building a generic 'Wizard' component for multi-step processes. The Wizard is a wrapper that takes an array of 'panel' component properties, and exposes navigation logic to each of them through an IWizardPanelProps interface.</p>
  
  <p>The implementation of the Wizard component and the panel interfaces is below:</p>
  
  <pre><code>export interface IWizardPanelProps {
    changePanel: (increment: number) =&gt; void;
  }
  
  export class WizardPanel&lt;T&gt; extends React.Component&lt;IWizardPanelProps &amp; T&gt;{
    constructor(props: IWizardPanelProps &amp; T) {
      super(props);
    }
  }
  
  interface IWizardProps {
    panelComponents: (typeof WizardPanel)[],
    showControls?: boolean // Hidden by default - assumes panels themselves handle pagination
  }
  
  interface IWizardState {
    panelIndex: number
  }
  
  export class Wizard extends React.Component&lt;IWizardProps, IWizardState&gt; {
    constructor(props: IWizardProps) {
      super(props);
  
      this.state = {
        panelIndex: 0
      }
    }
  
    changePanel = (increment: number) =&gt; {
      const newIndex = this.state.panelIndex + increment;
  
      this.setState({ panelIndex: newIndex });
    };
  
    render() {
      const { panelComponents, showControls } = this.props;
  
      return (
        &lt;div&gt;
          &lt;p&gt;&lt;strong&gt;Ye olde Wizard Component! (This is a placeholder, but the functionality is mostly there)&lt;/strong&gt;&lt;/p&gt;
          {panelComponents.map((Panel, key) =&gt; (
            &lt;div className={key === this.state.panelIndex ? undefined : 'hidden'} key={key}&gt;{&lt;Panel {...this.props} changePanel={this.changePanel}&gt;&lt;/Panel&gt;}&lt;/div&gt;
          ))}
          {showControls &amp;&amp; &lt;div&gt;
              &lt;button disabled={this.state.panelIndex === 0} onClick={() =&gt; this.changePanel(-1)}&gt;
              Previous
            &lt;/button&gt;
            &lt;button disabled={this.state.panelIndex === panelComponents.length - 1} onClick={() =&gt; this.changePanel(1)}&gt;
              Next
            &lt;/button&gt;
          &lt;/div&gt;}
        &lt;/div&gt;
      );  
    }
  }
  </code></pre>
  
  <p>Then when we create a panel component, we do so like this:</p>
  
  <pre><code>interface IMyPanelProps {
    ...
  }
  
  
  export class MyPanel extends WizardPanel&lt;IMyPanelProps&gt; {
    constructor(props: IWizardPanelProps &amp; IMyPanelProps) {
      super(props);
    }
    render() {
      ...
    }
    ...
  }
  </code></pre>
  
  <p>Good so far right?</p>
  
  <p>But then when we go to implement a Wizard like so:</p>
  
  <pre><code>&lt;Wizard panelComponents={[ MyPanel ]}&gt;&lt;/Wizard&gt;
  </code></pre>
  
  <p>We get the following error:</p>
  
  <blockquote>
    <p>Type '(typeof MyPanel)[]' is not assignable to type '(typeof
    WizardPanel)[]'.</p>
    
    <p>Type 'typeof MyPanel' is not assignable to type 'typeof
    WizardPanel'.</p>
    
    <p>Type 'MyPanel' is not assignable to type 'WizardPanel'.</p>
    
    <p>Types of property 'props' are incompatible.</p>
    
    <p>Type 'Readonly&lt;{ children?: ReactNode; }> &amp; Readonly&lt; IWizardPanelProps &amp; IMyPanelProps>' is not assignable to type 'Readonly&lt; { children?: ReactNode; }> &amp; Readonly&lt; IWizardPanelProps &amp; T>'.</p>
    
    <p>Type 'Readonly&lt;{ children?: ReactNode; }> &amp; Readonly &lt; IWizardPanelProps &amp; IMyPanelProps>' is not assignable to type 'Readonly &lt; IWizardPanelProps &amp; T>'.</p>
  </blockquote>
  
  <p>What gives? It seems like it comes down to this last line:</p>
  
  <p><code>Readonly&lt;{ children?: ReactNode; }&gt; &amp; Readonly&lt; IWizardPanelProps  &amp; IMyPanelProps&gt;' is not assignable to type 'Readonly&lt; IWizardPanelProps  &amp; T&gt;</code></p>
  
  <p>but I don't understand what I've done wrong. How are we missing the <code>Readonly&lt;{ children?: ReactNode; }&gt;</code> in the IWizardProps declaration of propComponents??</p>