[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>;
        }}
      />
    </>
  );
};

 

posted @   Zhentiw  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源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
点击右上角即可分享
微信分享提示