[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>;
}}
/>
</>
);
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-08-29 [Typescript] Step 4. ESLint for Typescript
2022-08-29 [Typescript] Step 3. Turn on "noImplicitAny" and even more strict mode
2022-08-29 [Typescript] Step1 & 2 for converting a js app to ts
2019-08-29 [React + GraphQL] Use useLazyQuery to manually execute a query with Apollo React Hooks
2019-08-29 [CSS] Conditionally Assign Style to a Parent Element with Focus-Within Pseudo-class
2019-08-29 [Angular 8] Calculate and Measure Performance budgets with the Angular CLI
2019-08-29 [Angular 8] Custom Route Preloading with ngx-quicklink and Angular