I'm writing a React higher-order component (HOC) with TypeScript. The HOC should accept one more prop than the wrapped component, so I wrote this:
type HocProps {
// Contains the prop my HOC needs
thingy: number
}
type Component<P> = React.ComponentClass<P> | React.StatelessComponent<P>
interface ComponentDecorator<TChildProps> {
(component: Component<TChildProps>): Component<HocProps & TChildProps>;
}
const hoc = function<TChildProps>(): (component: Component<TChildProps>) => Component<HocProps & TChildProps) {
return (Child: Component<TChildProps>) => {
class MyHOC extends React.Component<HocProps & TChildProps, void> {
// Implementation skipped for brevity
}
return MyHOC;
}
}
export default hoc;
In other words, hoc is a function that yields the actual HOC. This HOC is (I believe) a function that accepts a Component. Since I don't know in advance what the wrapped component will be, I'm using a generic type TChildProps to define the shape of the props of the wrapped component. The function also returns a Component. The returned component accepts props for the wrapped component (again, typed using the generic TChildProps) and some props it needs for itself (type HocProps). When using the returned component, all of the props (both HocProps and the props for the wrapped Component) should be supplied.
Now, when I attempt to use my HOC, I do the following:
// outside parent component
const WrappedChildComponent = hoc()(ChildComponent);
// inside parent component
render() {
return <WrappedChild
thingy={ 42 }
// Prop `foo` required by ChildComponent
foo={ 'bar' } />
}
But I get a TypeScript error:
TS2339: Property 'foo' does not exist on type 'IntrinsicAttributes & HocProps & {} & { children? ReactNode; }'
It seems to me TypeScript is not replacing TChildProps with the shape the of the props needed for ChildComponent. How can I make TypeScript do that?