I was wondering if it was possible to type a JSX element (or component) that returns a single function as its child?
An example:
interface ComponentChildrenProps {
someProp: string;
}
const Component: React.FC<ComponentProps> = ({ children }): JSX.Element => {
const propsForChildren: ComponentChildrenProps = { ... }
const childrenFunction = children as (props: ComponentChildrenProps) => ReactNode;
return <div>{children && childrenFunction(propsForChildren)}</div>
}
So in this case, I return only a JSX.Element, but I was wondering if it was possible to actually type the Component to return a JSX.Element that outputs a single function as its child.
Kind of like
const Component = (props): JSX.Element<{(props: propsForChildren) => ReactNode}> =>
{ ...component code }
In essence, I would like TS to autocomplete the Component props when I open the function inside of it, and I was wondering if that was possible
Edit:
This is a kind of generic form component. I'll attach a semi practical use of it below (I stripped it from most of its inner workings not to add too much confusion):
const Form: React.FC<FormProps> = (props): JSX.Element | null => {
const { ... } = props;
const { handleSubmit, control, watch, formState } = useForm(props)
const childrenFunction = children as (props: FormChildrenProps) => ReactNode;
if (!children) return null;
return (
<form id={id} onSubmit={handleSubmit(onValidSubmit)}>
{childrenFunction({ control, formState, watch })}
</form>
);
};
Usage:
<Form>
{({ control, watch }: FormChildrenProps) => (
<section>
<TextField control={control} label="foo" name="foo" />
<TextField control={control} label="bar" name="bar" />
</section>
)}
</Form>