There just no code to handle this case. I was working for library that wraps components with proxy.
So full here typesafe implementation of wrapping components with proxy.
const REACT_MEMO_TYPE = Symbol.for("react.memo");
const REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref");
const REACT_LAZY_TYPE = Symbol.for("react.lazy");
// const enum LazyStatus {
// Uninitialized = -1,
// Pending = 0,
// Resolved = 1,
// Rejected = 2,
// }
type RealComponentType<TProps extends object, IRef = unknown> =
| {
$$typeof: typeof REACT_FORWARD_REF_TYPE;
render: (props: TProps, ref: null | Ref<IRef>) => ReactNode;
}
| {
$$typeof: typeof REACT_MEMO_TYPE;
compare: null | ((a: TProps, b: TProps) => boolean);
type: (props: TProps) => ReactNode;
}
| {
$$typeof: typeof REACT_LAZY_TYPE;
_status: -1 | 0 | 1 | 2;
_result: unknown;
}
| React.ComponentClass<TProps>
| React.FC<TProps>;
type ReactFunctionalComponentType<
TProps extends object,
IRef = unknown
> = Extract<
RealComponentType<TProps, IRef>,
{ $$typeof: typeof REACT_FORWARD_REF_TYPE } | React.FC<TProps>
>;
const wrapFunctionalFROrDefault = <TProps extends object>(
Component: ReactFunctionalComponentType<TProps>,
handler: HocTransformer
) => {
type ForwardRefComponent = Extract<
ReactFunctionalComponentType<TProps>,
{ $$typeof: typeof REACT_FORWARD_REF_TYPE }
>;
type RegularFunctionComponent = Exclude<
ReactFunctionalComponentType<TProps>,
ForwardRefComponent
>;
if (
"$$typeof" in Component &&
Component["$$typeof"] === REACT_FORWARD_REF_TYPE
) {
return {
$$typeof: REACT_FORWARD_REF_TYPE,
render: new Proxy((Component as ForwardRefComponent).render, handler),
};
}
return new Proxy(Component as RegularFunctionComponent, handler);
};
// I don't know why but typescript is not helpful at all
// Component can be memo class component or wrapped in hoc functional component
export const wrapComponentIntoHoc = <TProps extends object>(
Component: RealComponentType<TProps>,
handler: HocTransformer,
mimicToNewComponentHandler: null | MimicToNewComponentHandler
) => {
// this case assumes that it's ClassComponent
if (isClassComponent(Component)) {
return wrapFunctionalFROrDefault(
toFunctional(Component) as React.FC<TProps>,
handler
);
}
if ("$$typeof" in Component && Component["$$typeof"] === REACT_MEMO_TYPE) {
return {
$$typeof: REACT_MEMO_TYPE,
// @ts-expect-error
type: wrapFunctionalFROrDefault(toFunctional(Component.type), handler),
compare: Component.compare,
};
}
if (
"$$typeof" in Component &&
Component["$$typeof"] === REACT_FORWARD_REF_TYPE
) {
return {
$$typeof: REACT_FORWARD_REF_TYPE,
// render is always function
render: new Proxy(Component.render, handler),
};
}
if ("$$typeof" in Component && Component["$$typeof"] === REACT_LAZY_TYPE) {
return Component;
}
const proxied = new Proxy(Component, handler);
return mimicToNewComponentHandler
? new Proxy(proxied, mimicToNewComponentHandler)
: proxied;
};
There just no code to handle this case. I was working for library that wraps components with proxy. So full here typesafe implementation of wrapping components with proxy.