I am trying to write a React Context HOC function so that I can wrap other components with the Context allowing me to send all notifications to a single component. I had to piece together a working solution from a few different guides, mainly this one as none of them quite worked in their original form.
What I ended up with is something like this:
HOC:
import * as React from "react";
import { INotificationContextState, NotificationConsumer } from "./NotificationContext";
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export default function withNotificationContext<
P extends { notificationContext?: INotificationContextState },
R = Omit<P, 'notificationContext'>
>(
Component: React.ComponentClass<P> | React.StatelessComponent<P>
): React.SFC<R> {
return function BoundComponent(props: R) {
return (
<NotificationConsumer>
{value => <Component {...props} notificationContext={value} />}
</NotificationConsumer>
);
};
}
Context:
interface IMessage {
message: string;
key: number;
}
interface INotificationState {
open: boolean;
messageInfo: IMessage;
timeOut: number;
}
interface INotificationContextState extends INotificationState {
handleClick(message: string): void;
handleClose(event: React.MouseEvent<HTMLElement>, reason: any): void;
handleExited(): void;
}
const NotificationContext = React.createContext<INotificationContextState | null>(
null
);
class NotificationProvider extends React.Component {
public state: Readonly<INotificationState> = DEFAULT_STATE;
private queue: IMessage[] = [];
constructor(props: INotificationContextState) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.handleClose = this.handleClose.bind(this);
}
// rest of the class methods...
}
export const NotificationConsumer = NotificationContext.Consumer;
The HOC file gives me a red underline under the word Component in the line {value => <Component {...props} notificationContext={value} />}
The error reads as follows:
Type 'R & { notificationContext: INotificationContextState | null; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'. Type 'R & { notificationContext: INotificationContextState | null; }' is not assignable to type 'P'.ts(2322)
The strange thing is that this error does not prevent me from running the app, and furthermore the wrapper function works exactly like it should, and the wrapped component is able to pass notifications to the Notification object.
Part of my trouble is being unfamiliar with the Omit/Pick syntax and trying to mentally work out exactly what the type definition of "P" is in this context. I just have no idea why it generates an error, yet still works.