In React with material-ui I am trying to create a JSX component that accepts generic parameters and also uses the withStyles
HOC to inject my styles.
The first approach was like this:
const styles = (theme: Theme) => createStyles({
card: {
...
}
});
interface Props<T> {
prop: keyof T,
...
}
type PropsWithStyles<T> = Props<T> & WithStyles<typeof styles>;
export default withStyles(styles)(
class BaseFormCard<T> extends React.Component<PropsWithStyles<T>> {
...
}
),
But when trying to use this, the generic types are lost
<BaseFormCard<MyClass> prop={ /* no typings here */ } />
The only solution I could find was to wrap the export in a function which takes the generic parameter and constructs the component.
export default function WrappedBaseFormCard<T>(props: Props<T>): ReactElement<Props<T>> {
const wrapper = withStyles(styles)(
class BaseFormCard<T> extends React.Component<PropsWithStyles<T>> {
...
}
) as any;
return React.createElement(wrapper, props);
}
However this is ridiculously complicated and even comes with runtime cost, although it is only trying to solve problems typings.
There has to be a better way to use JSX components with generic parameters and HOCs.
This is closely related to the issue here https://github.com/mui-org/material-ui/issues/11921, but there was never satisfying solution and the issue is now closed.