
React 19 부터는 forwardRef 가 deprecated 되었지만, 많은 프로젝트에선 React 18 이하를 사용하고 있다.
forwardRef 는 제네릭 컴포넌트의 타입을 제대로 추론하지 못한다는 단점이 있어 이를 래핑한 함수를 사용하는 방식으로 그 단점을 우회하곤 한다.
https://www.totaltypescript.com/forwardref-with-generic-components
import React from "react";
function fixedForwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode
): (props: P & React.RefAttributes<T>) => React.ReactNode {
return React.forwardRef(render) as any;
}
다만 위와 같은 래핑된 함수에서 React.forwardRef(render) 부분에서 render 의 타입이 맞지 않는다는 에러가 날 때가 있었다. 마음편하게 render as any 로 사용해도 되지만, React 라이브러리 코드에서는 any 로 타입 에러를 우회하기 껄끄러웠다.
그래서 아래와 같이 명확한 타입을 지정해서 사용할 수 있도록 만들어보았다.
import {
type PropsWithoutRef,
type ReactElement,
type Ref, type RefAttributes,
forwardRef
} from 'react'
/**
* A utility that allows creating a forwardRef component that can accept generic props.
* React.forwardRef does not support this out of the box.
*/
export function genericForwardRef<TRef, TProp = object>(
render: (
props: PropsWithoutRef<TProp>, ref: Ref<TRef>
) => ReactElement | null
) {
return forwardRef(render) as
(props: TProp & RefAttributes<TRef>) => ReactElement | null
}