Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: TypeScript 5.5 breaks components using generic forwardRef #28605

Open
andrew-pledge-io opened this issue Jul 15, 2024 · 3 comments
Open

Comments

@andrew-pledge-io
Copy link

andrew-pledge-io commented Jul 15, 2024

Describe the bug

Upgrading to TypeScript 5.5 gives the following error:

src/Test.stories.tsx(7,3): error TS2322: Type '<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode' is not assignable to type 'ComponentType<Record<string, unknown> extends Required<ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>> ? any : ComponentProps<...>> | undefined'.
  Type '<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode' is not assignable to type 'FunctionComponent<Record<string, unknown> extends Required<ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>> ? any : ComponentProps<...>>'.
    Types of parameters 'props' and 'props' are incompatible.
      Type 'Record<string, unknown> extends Required<ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>> ? any : ComponentProps<...>' is not assignable to type 'TestProps<ElementType> & RefAttributes<HTMLDivElement>'.
        Type 'ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>' is not assignable to type 'TestProps<ElementType> & RefAttributes<HTMLDivElement>'.
          Type '{} | (TestProps<ElementType> & RefAttributes<HTMLDivElement>)' is not assignable to type 'TestProps<ElementType> & RefAttributes<HTMLDivElement>'.
            Type '{}' is not assignable to type 'TestProps<ElementType> & RefAttributes<HTMLDivElement>'.
              Property 'test' is missing in type '{}' but required in type 'TestProps<ElementType>'.
                Type 'ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>' is not assignable to type 'TestProps<ElementType>'.
                  Type '{} | (TestProps<ElementType> & RefAttributes<HTMLDivElement>)' is not assignable to type 'TestProps<ElementType>'.
                    Type '{}' is not assignable to type 'TestProps<ElementType>'.
                      Type 'Record<string, unknown> extends Required<ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>> ? any : ComponentProps<...>' is not assignable to type 'TestProps<ElementType>'.
                        Type 'ComponentProps<(<T extends ElementType>(props: TestProps<T> & RefAttributes<HTMLDivElement>) => ReactNode)>' is not assignable to type 'TestProps<ElementType>'.
                          Type '{} | (TestProps<ElementType> & RefAttributes<HTMLDivElement>)' is not assignable to type 'TestProps<ElementType>'.
                            Property 'test' is missing in type '{}' but required in type 'TestProps<ElementType>'.
src/Test.stories.tsx(13,14): error TS2322: Type '{ args: { test: string; }; }' is not assignable to type 'Story'.

The error is only on components that use the "generic forwardRef" pattern (described here in the React TypeScript cheat sheet).

This pattern is fairly common in component libraries as it's required to support generics on components using forwardRef.

The error isn't present in TypeScript 5.4. It's also not present in TypeScript 5.5 when using forwardRef as imported directly from React.

Reproduction link

https://stackblitz.com/edit/vitejs-vite-gwnmdk?file=src%2FTest.stories.tsx&view=editor

Reproduction steps

  1. Go to the above link
  2. Run npm run build

System

Storybook Environment Info:

  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm <----- active
    pnpm: 8.15.6 - /usr/local/bin/pnpm

Additional context

No response

Copy link
Contributor

greptile-apps bot commented Jul 15, 2024

** Disclaimer** This information might be inaccurate, due to it being generated automatically
To resolve the TypeScript 5.5 issue with generic forwardRef, update the Button component in /code/renderers/react/template/stories/docgen-components/8894-9511-ts-forward-ref/input.tsx as follows:

import React, { forwardRef, ElementType, RefAttributes } from 'react';

interface ButtonProps<T extends ElementType> {
  as?: T;
  disabled?: boolean;
  variant?: 'primary' | 'secondary';
}

const Button = forwardRef<HTMLButtonElement, ButtonProps<ElementType>>((props, ref) => {
  const { as: Component = 'button', disabled, variant, ...rest } = props;
  return <Component ref={ref} disabled={disabled} className={variant} {...rest} />;
});

Button.displayName = 'Button';

export default Button;

Ensure that the ButtonProps interface and forwardRef usage align with the updated TypeScript 5.5 requirements.

References

/code/renderers/react/template/stories/docgen-components/8894-9511-ts-forward-ref
/code/renderers/react/template/stories/docgen-components/8143-ts-react-fc-generics
/code/renderers/react/template/stories/docgen-components/ts-react-fc

About Greptile

This response provides a starting point for your research, not a precise solution.

Help us improve! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

Ask Greptile · Edit Issue Bot Settings

@valentinpalkovic
Copy link
Contributor

Hi @andrew-pledge-io

Thank you for the report! Would you mind opening a PR to fix these issues?

@jakubmazanec
Copy link

I did some investigation: microsoft/TypeScript#59490

So now I'm using this:

const meta = {
  component: SomeComponent,
} satisfies Meta<SomeComponentProps>; // instead of using `typeof SomeComponent`;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants