Fix forwardRef globally
To jump ahead to the solution, uncommenting the following code from Stefan Baumgartner will globally override the value of forwardRef
:
declare module "react" {
function forwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode
): (props: P & React.RefAttributes<T>) => React.ReactNode;
}
This is a good snippet to have on hand when using forwardRef
in your TypeScript projects, but there are some tradeoffs, though.
With the above solution, when we go to use ForwardReffedTable
, we no longer have access to defaultProps
and some of React's other properties even though we do have proper inference for the generic component.
Fix forwardRef locally
import { ForwardedRef, forwardRef, useRef } from "react";
import { Equal, Expect } from "../helpers/type-utils";
function fixedForwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode,
): (props: P & React.RefAttributes<T>) => React.ReactNode {
return forwardRef(render) as any;
}
type Props<T> = {
data: T[];
renderRow: (item: T) => React.ReactNode;
};
export const Table = <T,>(
props: Props<T>,
ref: ForwardedRef<HTMLTableElement>,
) => {
return <table ref={ref} />;
};
const ForwardReffedTable = fixedForwardRef(Table);
const Parent = () => {
const tableRef = useRef<HTMLTableElement>(null);
const wrongRef = useRef<HTMLDivElement>(null);
return (
<>
<ForwardReffedTable
ref={tableRef}
data={["123"]}
renderRow={(row) => {
type test = Expect<Equal<typeof row, string>>;
return <div>123</div>;
}}
/>
<ForwardReffedTable
// @ts-expect-error
ref={wrongRef}
data={["123"]}
renderRow={(row) => {
return <div>123</div>;
}}
/>
</>
);
};
- Typescript forwardRef Fixing React Typetypescript forwardref fixing react react typescript inference fixing forwardref typescript react useimperativehandle forwardref react typescript this type type typescript expression error performance typescript interface type typescript predicates type all element invalid react type typescript interface type