I'm trying to make a utility function that creates a new react component from a different react component that accepts different set of props. I have following code:
function makeNewComponent(
OldComponent: React.ComponentType<any>,
prepareProps: () => typeof OldComponent.propTypes
): React.ComponentType {
return function NewComponent() {
const oldComponentProps = prepareProps();
return <OldComponent {...oldComponentProps} />;
};
}
But it's not inferring return type of the prepareProps
function properly. For example if I use the makeNewComponent
function like this:
const OldComponent: React.FC<{ num1: number }> = () => {
return <div>hello</div>;
};
const NewComponent = makeNewComponent(OldComponent, () => ({}));
Typescript infers the return type of the prepareProps
function as
prepareProps: () => React.WeakValidationMap<{}> | undefined
but I need it to be like this:
prepareProps: () => { num1: number; }
I have tried different things but I can't get it to work. I also tried nesting some functions like following:
function makeNewComponent2(OldComponent: React.ComponentType<any>) {
return function (prepareProps: () => typeof OldComponent.propTypes) {
return function NewComponent() {
const oldComponentProps = prepareProps();
return <OldComponent {...oldComponentProps} />;
};
};
}
But it's still not working. Any solution?
CodePudding user response:
The following would do the trick:
type ExtractPropTypes<T> = T extends React.WeakValidationMap<infer P> ? P : never;
function makeNewComponent<T extends React.ComponentType<any>>(
Component: T,
prepareProps: () => ExtractPropTypes<T['propTypes']>
): React.ComponentType {
return function NewComponent() {
const props = prepareProps();
return <Component {...props} />;
};
}