Reputation: 6476
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.
Upvotes: 0
Views: 201
Reputation: 344
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
Upvotes: 1