Spadar Shut
Spadar Shut

Reputation: 15807

TS/React passing ref to a component with forwardRef

I have a component with forwardRef and want to use it inside another component with forwardRef:


const DEFAULT_ELEMENT = "button";

export type PropsOf<TTag = any> = TTag extends React.ElementType
  ? React.ComponentProps<TTag>
  : never;

export type ButtonProps = PropsOf<typeof DEFAULT_ELEMENT> & {};

// custom button, works fine:
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  (props, ref) => (<button ref={ref} {...props}/>)
)

// Same component, but uses the previous one, TS complains about refs:
export const IconButton = forwardRef<HTMLButtonElement, ButtonProps>(
(props, ref) => (
  <Button
    ref={ref} //<- Here TS shows error
    // TS2322: Type 'string | ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null'
    // is not assignable to type 'Ref<HTMLButtonElement> | undefined'.
    //   Type 'string' is not assignable to type 'Ref<HTMLButtonElement> | undefined'.
    {...props}
  />
))

Here's an image for better readability:

ts error

React should accept its own refs, but it's complaining. What's wrong with the code, how to fix the error?

Upvotes: 0

Views: 60

Answers (1)

jmk
jmk

Reputation: 1610

The problem here lies in ButtonProps type: it contains ref property.

You can omit it by:

export type ButtonProps = Omit<PropsOf<typeof DEFAULT_ELEMENT>, 'ref'>;

Upvotes: 1

Related Questions