React >=18
In React 18 the FunctionalComponent interface has changed to become:
interface FunctionComponent<P = {}> {
(props: P, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P> | undefined;
contextTypes?: ValidationMap<any> | undefined;
defaultProps?: Partial<P> | undefined;
displayName?: string | undefined;
}
Note that the PropsWithChildren type is omitted from the props type of a FunctionalComponent after React 18, this means that you have to include the children prop yourself:
interface Props {
children: React.ReactNode;
}
export const PageViewTracker: React.FC<Props> = ({ children }) => {
}
The reason why they removed the implicit children prop can be found here. (source of React 18’s Type definition release notes).
The PropsWithChildren type is still available within the typings of React, so if you still want to optionally have children as props just like versions before React 18, you can still do:
import { PropsWithChildren } from 'react';
interface Props {
foo: string;
}
export const PageViewTracker: React.FC<PropsWithChildren<Props>> = ({ children, foo }) => {
}
The type definition of PropsWithChildren is:
type PropsWithChildren<P = unknown> = P & { children?: ReactNode | undefined };
React <=17
The reason why you’re getting that error is because you’re giving the ‘ReactNode’ interface to an object ({}: Type). children itself is of the type ReactNode:
type PropsWithChildren<P> = P & { children?: ReactNode };
You should give your PageViewTracker the FunctionComponent (or its alias FC) type.
export const PageViewTracker: React.FC = ({ children }) => {
...
}
which has the following interface:
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement | null;
propTypes?: WeakValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}
So by default it accepts the children prop which has the type ‘ReactNode’.