0
votes

I have a use case where I'd like to restrict what type of elements can be used as children. I've attempted to do this in the example below, but I get the following error:

Type 'Element' is not assignable to type 'FC<{ a: number; }> | (FC<{ a: number; }> & string) | (FC<{ a: number; }> & number) | (FC<{ a: number; }> & false) | (FC<{ a: number; }> & true) | (FC<{ a: number; }> & ReactElement<...>) | (FC<...> & ReactNodeArray) | (FC<...> & ReactPortal)'. Type 'Element' is not assignable to type 'FC<{ a: number; }> & ReactPortal'. Type 'Element' is not assignable to type 'FC<{ a: number; }>'. Type 'Element' provides no match for the signature '(props: PropsWithChildren<{ a: number; }>, context?: any): ReactElement<any, any> | null'.ts(2322) App.tsx(7, 30): The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & { children: FC<{ a: number; }>; } & { children?: ReactNode; }'

Here's the code:

import * as React from 'react';

const ComponentA: React.FC<{a: number}> = ({ a }) => (
  <div>{a}</div>
);

const ComponentB: React.FC<{ children: typeof ComponentA}> = props => (
  <div>{props.children}</div>
);

export default function App() {
  return (
    <div className="App">
      <ComponentB>
        <ComponentA a={2} />
      </ComponentB>
    </div>
  );
}

And a link to a sandbox showing the problem.

1
Try React.FC<{a: number}> instead of typeof ComponentA.windowsill
@windowsill same error, I'm afraidOliverRadini

1 Answers

1
votes

separating types into interfaces seem to be a nice idea here.


    import * as React from "react";

    interface ComponentAProps {
      a: number;
    }
    const ComponentA: React.FC<ComponentAProps> = ({ a }) => <div>{a}</div>;

    interface ComponentBProps {
      children?: React.ReactElement<ComponentAProps>;
    }
    const ComponentB: React.FC<ComponentBProps> = (props) => (
      <div>{props.children}</div>
    );

    export default function App() {
      return (
        <div className="App">
          <ComponentB>
            <ComponentA a={2} />
          </ComponentB>
        </div>
      );
    }

Sandbox here https://codesandbox.io/s/beautiful-visvesvaraya-63rhp?file=/src/App.tsx