TypeScript Happy Forward Ref
Make React’s forwardRef works with TypeScript in case:
- You want to make a polymorphic component with forwarded ref
- You want to pass generic type to
forwardRef - You have encountered a strange typescript quirk when an interface function object can not be nested
Usage
Below is an example that uses typescriptHappyForwardRef and other foxact utilities to create a polymorphic button component with forwarded ref.
import { createPolymorphic, type PolymorphicComponentProps } from 'foxact/polymorphic';
import { mergeProps } from 'foxact/merge-props';
import { typescriptHappyForwardRef } from 'foxact/typescript-happy-forward-ref';
import { mergeRefs } from 'foxact/merge-refs';
const { renderPolymorphic } = createPolymorphic('as');
type ButtonProps<C extends React.ElementType = 'button'> =
PolymorphicComponentProps<'as', C, { variant?: 'primary' | 'secondary' }>;
export const Button = typescriptHappyForwardRef(
function Button<C extends React.ElementType = 'button'>(
{ variant, ...rest }: ButtonProps<C>,
ref: React.ForwardedRef<HTMLButtonElement>
) {
const internalRef = useRef<HTMLButtonElement>(null);
return renderPolymorphic({
props: mergeProps(
{ className: `btn${variant ? ` btn-${variant}` : ''}`, style: { display: 'inline-flex' } },
rest
),
defaultComponent: 'button',
ref: mergeRefs(ref, internalRef),
});
}
);