[React Typescript] Fixing forwardRef's Type
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 { Equal, Expect } from "../helpers/type-utils";
import { ForwardedRef, forwardRef, useRef } from "react";
type FixedForwardRef = <T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode,
) => (props: P & React.RefAttributes<T>) => React.ReactNode;
const fixedForwardRef = forwardRef as FixedForwardRef;
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>;
}}
/>
</>
);
};

浙公网安备 33010602011771号