简体   繁体   中英

React.ForwardRef TypeScript Component Type Error

I have a Block component which will render a div or a tag based on a prop value. I want to pass a ref from the parent component to this component. Therefore, I need to use RefForwardingComponent type for my component variable type, but I get an error for type incompatibility between HTMLAnchorElement and HTMLDivElement . How can I fix it? here's the component code on CodeSandBox :

import * as React from "react";

interface Props {
  isLink: boolean;
}

type PropsWithElementProps<T> = React.HTMLProps<T> & Props;

type RefComponent<T, U> =
  | React.RefForwardingComponent<T, PropsWithElementProps<T>>
  | React.RefForwardingComponent<U, PropsWithElementProps<U>>;

// error for Block variable type... full error on CodeSandBox link
const Block: RefComponent<HTMLAnchorElement, HTMLDivElement> = React.forwardRef(
  ({ isLink }, ref) => {
    if (isLink)
      return (
        <a ref={ref} href="#nothing">
          I'm a link!
        </a>
      );
    else return <div ref={ref}>I'm a div!</div>;
  }
);

export default Block;

React.forwardedRef expects you to provide a type for the returned element and the props in cases where it cannot be inferred. You can indicate it like this:

import * as React from "react";

interface Props {
  isLink?: boolean;
}

const Block = React.forwardRef<HTMLAnchorElement & HTMLDivElement, Props>(
  ({ isLink = false }, ref) => {
    return isLink ? (
      <a ref={ref} href="#nothing">
        {"I'm a link!"}
      </a>
    ) : (
      <div ref={ref}>{"I'm a div!"}</div>
    );
  }
);

export default Block;

The forwardRef type definition looks like this:

function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM