ForwardRefExoticComponent
The definition taken from here is
interface ExoticComponent<P = {}> {
/**
* **NOTE**: Exotic components are not callable.
*/
(props: P): (ReactElement|null);
readonly $$typeof: symbol;
}
interface NamedExoticComponent<P = {}> extends ExoticComponent<P> {
displayName?: string;
}
interface ForwardRefExoticComponent<P> extends NamedExoticComponent<P> {
defaultProps?: Partial<P>;
propTypes?: WeakValidationMap<P>;
}
If you write it out you get
interface ForwardRefExoticComponent<P> {
/**
* **NOTE**: Exotic components are not callable.
*/
(props: P): (ReactElement|null);
readonly $$typeof: symbol;
displayName?: string;
defaultProps?: Partial<P>;
propTypes?: WeakValidationMap<P>;
}
ForwardRefRenderFunction
The definition taken from here is
interface ForwardRefRenderFunction<T, P = {}> {
(props: PropsWithChildren<P>, ref: ((instance: T | null) => void) | MutableRefObject<T | null> | null): ReactElement | null;
displayName?: string;
// explicit rejected with `never` required due to
// https://github.com/microsoft/TypeScript/issues/36826
/**
* defaultProps are not supported on render functions
*/
defaultProps?: never;
/**
* propTypes are not supported on render functions
*/
propTypes?: never;
}
Differences
ForwardRefRenderFunction
does not support propTypes
and defaultProps
, whereas ForwardRefExoticComponent
does.
ForwardRefExoticComponent
has an additional member $$typeof
of type symbol
- The call signature of
ForwardRefRenderFunction
takes a props
object, which must include a member children
and a ref object as parameters, whereas the call signature of ForwardRefExoticComponent
only takes a props object of arbitrary shape as parameter.
Some more thoughts
The interplay of those two definitions is best seen in the definition of the forwardRef
function:
function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
Also, a big difference between the two definitions seems to be, that ForwardRefExoticComponent
(like all exotic components) are no function components, but actually just objects, which are treated specially when rendering them. Therefore the comment
NOTE: Exotic components are not callable.
And for some reason, those exotic components are necessary in some places.