polymorphic-react-component icon indicating copy to clipboard operation
polymorphic-react-component copied to clipboard

TS Error Type 'ForwardRefExoticComponent<Omit<TextProps<ElementType<any>>, "ref"> & RefAttributes<unknown>>' is not assignable to type 'TextComponent'.

Open neznayer opened this issue 1 year ago • 8 comments

Firstly, thank you for an amazing and very thorough tutorial on logrocket!

I've followed the tutorial, and had this error on the Text compomnent:

Type 'ForwardRefExoticComponent<Omit<TextProps<ElementType<any>>, "ref"> & RefAttributes<unknown>>' is not assignable to type 'TextComponent'.
  Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | null'.
    Type 'undefined' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | null'.(2322)

Check it in the TS playground: Typescript playground

neznayer avatar Aug 30 '23 09:08 neznayer

Due to the Typescript version. An error appears on ^4.9.5 but ^4.7.4 doesn't. Someone Typescript expert can resolve that.

hungify2022 avatar Oct 30 '23 01:10 hungify2022

Did anyone solve this?

bitabs avatar Nov 05 '23 20:11 bitabs

export const Text = React.forwardRef(
  <C extends React.ElementType = "span">(
    { as, color, children }: TextProps<C>,
    ref?: PolymorphicRef<C>
  ) => {
    const Component = as || "span";

    const style = color ? { style: { color } } : {};

    return (
      <Component {...style} ref={ref}>
        {children}
      </Component>
    );
  }
// add this
) as TextComponent;

cyhfe avatar Nov 27 '23 08:11 cyhfe

Change the return type as in the comment below.

type TextComponent = <C extends React.ElementType = "span">(
  props: TextProps<C>
) => React.ReactElement | null; // Change this to React.ReactNode | null;

ozguruysal avatar Dec 05 '23 14:12 ozguruysal

It still gives me error.

Type 'ForwardRefExoticComponent<Omit<TextProps<ElementType<any>>, "ref"> & RefAttributes<unknown>>' is not assignable to type 'TextComponent'.
  Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | null'.
    Type 'undefined' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>> | null'.ts(2322)
``

hungify avatar Dec 14 '23 13:12 hungify

@hungify not sure. I don't see any error when I make that change. Here's the playground link with the update I suggested above.

ozguruysal avatar Dec 15 '23 11:12 ozguruysal

@ozguruysal Thank you! But I have a new problem, how to resolve it

Text.displayName = 'Text';
Property 'displayName' does not exist on type 'TextComponent'.

Here is my idea

type TextComponent = (<C extends React.ElementType = 'span'>(
  props: TextProps<C>,
) => React.ReactNode | null) & {
  displayName?: string;
};

hungify avatar Dec 16 '23 04:12 hungify

I think that's because React.forwardRef() method's return type is overriden. I'm not 100% sure but maybe you can type the component like this so that you also get defaultProps and propTypes in case you need.

type TextComponent<C extends React.ElementType = "span"> = ((
  props: TextProps<C>
) => React.ReactNode | null) & React.ForwardRefExoticComponent<TextProps<C>>;

ozguruysal avatar Dec 16 '23 18:12 ozguruysal