HOC returned component props can not differ from HOC generic props
See original GitHub issueTypeScript Version: 3.3.0-dev.20181208
Search Terms:
- HOC
- react
- higher order component
Code
import * as React from 'react';
export interface HOCProps {
foo: number;
}
/** Remove props, that have been prefilled by the HOC */
type WithoutPrefilled<T extends HOCProps> = Pick<T, Exclude<keyof T, 'foo'>>;
function withFoo<P extends HOCProps>(WrappedComponent: React.ComponentType<P>) {
return class SomeHOC extends React.Component<WithoutPrefilled<P>> {
public render(): JSX.Element {
return <WrappedComponent {...this.props} foo={0} />;
}
};
}
Expected behavior: No error, like with every version below 3.2.0.
Actual behavior: Throws an error highlighting the WrappedComponent in the render method.
[ts]
Type 'Readonly<{ children?: ReactNode; }> & Readonly<Pick<P, Exclude<keyof P, "foo">>> & { foo: number; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Type 'Readonly<{ children?: ReactNode; }> & Readonly<Pick<P, Exclude<keyof P, "foo">>> & { foo: number; }' is not assignable to type 'P'. [2322]
Additional Information
This is pretty much the same sample example used in https://github.com/Microsoft/TypeScript/issues/28720, but with the difference, that the props of the returned component differ from the generic.
Basically the HOC prefills the foo
property for the WrappedComponent
. Since the spreaded props are overriden by foo
, I don’t want foo
to be a valid property for the HOC. This does not seem to be possible anymore.
Playground Link:
Related Issues: https://github.com/Microsoft/TypeScript/issues/28720
Issue Analytics
- State:
- Created 5 years ago
- Reactions:75
- Comments:19 (3 by maintainers)
Top Results From Across the Web
Typescript with React - use HOC on a generic component class
EDIT: The problem is that I want to be able to have something like <FooWithTd<number> {...someprops}/> later on, as I don't know the...
Read more >Typing Higher Order Components in React using TypeScript
I have a generic component A, whose props is type Props = PubProps<B> & InjectedProps ... React Higher Order Components (HOC) in TypeScript....
Read more >React Higher-Order Components in TypeScript - Medium
Here we are defining a component to return from the HOC, and specifying that the component will include the passed in component's props...
Read more >Section 1: React HOC docs in TypeScript
Example HOC from React Docs translated to TypeScript ... data: T; // data is generic ... P is the props of the wrapped...
Read more >React Higher-Order Components (HOCs) - Robin Wieruch
If the latter wouldn't be there, there would be a null pointer exception for the !props.data.length empty check. The withLoadingFeedback HOC is ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Starting with 3.2 the behaviour of the spread operator for generics has changed. Apparently the type of
props
gets erased as a negative side effect, but you can work around that by casting it back toP
using{...props as P}
when spreading back into the wrapped component.@ahejlsberg The change is that we no longer erase generics in JSX (so we actually check these calls now), and roughly that
Pick<P, Exclude<keyof P, "foo">> & { foo: P["foo"] }
doesn’t recombine to (or get recognized as assignable to)P
. It’s an unfortunate interaction with generic rest/spread, and the error we output is bad, too.