Type Inference in Higher order Components

Viewed 59

I have a HoC in React that simply passes an extra property called name:

export interface WithNameProps {
  name: string;
}
function withName<P extends {}>(Wrapped: React.ComponentType<P & WithNameProps>): React.FC<P> {
    const WithName: React.FC<P> = (props) => <Wrapped {...props} name="typescript" />
    return WithName;
}

However, when I use it with a component:

const Person: React.FC<{age: number, name: string}> = ({name, age}) => <p>Name: {name}. Age: {age}</p>

const Me = withName(Person);

<Me age={10} />

I get the following error:

Property 'name' is missing in type '{ age: number; }' but required in type '{ age: number; name: string; }'

Typescript is not able to infer that P here is {age: number, name: string} without WithNameProps i.e. {age: number}.

It works if I explicitly pass the type as in here:

const Me = withName<{age: number}>(Person);

It also works if the I declare the props of Person as an intersection type:

const Person: React.FC<{age: number} & {name: string}> = ({name, age}) => <p>Name: {name}. Age: {age}</p>

Here, Typescript is probably able to destructure the type and infer it.

Can I modify this in a way such that I don't have to explicitly state the type or pass the intersection type?

I have Typescript playground link here (along with a simpler example): Click here

0 Answers
Related