Home > other >  Infer second parameter type from first parameter type in typescript react
Infer second parameter type from first parameter type in typescript react

Time:08-21

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} />;
  };
}
  • Related