I write React component using TypeScript receiving as prop that may be either HTML tag or React component.
import * as React from 'react';
type MyComponentProps = {
as?: keyof HTMLElementTagNameMap | React.ComponentType<any>;
} & React.HTMLAttributes<HTMLElement>;
const MyComponent = React.forwardRef<HTMLElement, MyComponentProps>(({ as = 'div', ...props }, ref) => {
return React.createElement(as, { ref, ...props });
});
And assume we want to render MyComponent
as follow:
type WrappedComponentProps = {
prop1: string;
prop2: number;
};
const WrappedComponent: React.FC<WrappedComponentProps> = (props) => {
// some logic
};
<MyComponent as={WrappedComponent} prop1="some string" prop2={10} />
On the last line we can see TS error cause prop1 and prop2 naturally don't exist on MyComponentProps
.
So is it possible to declare something like that to be able to pick up wrapped component's props? Here is my pseudocode:
type MyComponentProps =
| ({
as?: keyof HTMLElementTagNameMap;
} & React.HTMLAttributes<HTMLElement>)
| ({
as?: React.ComponentType;
} & React.ComponentProps<as>);
That solution is working and there's no error:
type MyComponentProps =
| ({
as?: keyof HTMLElementTagNameMap;
} & React.HTMLAttributes<HTMLElement>)
| {
as?: React.ComponentType<any>;
[key: string]: any;
};
But I'd like to describe my type more clearly than just using [key: string]: any
.