Skip to content

React's ComponentProps type issues in TypeScript 5.5.4Β #59490

Closed
@jakubmazanec

Description

@jakubmazanec

πŸ”Ž Search Terms

react, forwardRef, component props, ComponentProps

πŸ•— Version & Regression Information

  • This changed between versions 5.4.5 and 5.5.5

⏯ Playground Link

https://www.typescriptlang.org/play/?jsx=4&ts=5.5.4#code/JYWwDg9gTgLgBAbwLACg5xgTzAUzgUQBscQcA7GAFWxwBpV0tc4BhCcCM8mABSgjABnemgw1W7SFwp8BggOrAYACwgBXGACUcAMxHod0AO4BDKABNtOuCcFwARrZwAxY2cu79Y5q6imLVtpk5jhQzmpkAMYwwJxeTHhW8eKyQooqLMrAhOZQ5CIAvnA6-CBwAER5JtHlANyoqDgAHpCwxRHRsWTFbgG6ADyUtHA8AHwAFAxwkZKc3ABccONg-EKLPMN5OotWg6MAlHAAvKNw2tUwAHTn0QByECEi+4vLq4LrcABkiHBbAPw7AaUU4FQ4nM44C7XSF3B54ZCiPIwNRQbqOQQuXoeHSTUToGYcaTwWxwCIAazIECM3RJvn82KCITCHRinH65Mp1OGHKpZFGXn29RQBQaKGarXgCTgAGVQGBiGxCdxUnYjiM3ullJlsrlyP0EfjCLZBLcTKQAXBBDAoMAyABzIUFUZCxotaDwHQsroyuUK2ZE15yRay8B+pUyN6HA2-HDI1FwMhqQiER2i8Xu7x4RVSbiaunuKwqwZwZowcjmOxEEjcai4U5HKbZuYRuSa9RaIGnb7Rw3G03mxZWm32oXodC2C2UOAAH1JwV0tpw5lHcAKLrFbraMzIVok4ZgeaxVmOPT8Bd0uPQxdL5crxFIFFreDV5UEYBMZHKEym6BWQb3OYUIeZ59DoRbAl46BbICOj9AAEpQACyAAyVYPjA-JTGCpw9jGcbdImyYrgUTzrlK2iCEmMAAIwnk2RJFgkEDWCG8o4PR3CjAA2uUkRGoIJpmjg5QALpCuROCUYQMAAEx0f6ypvP0THWBxQFKMo+agdxvH8YJpCibUcAAPTGSWUD8FAcDKKEOCisQ8B5FJNGAs5tEvoI7A4AAtHxxreWQQl1KgDkxs5MmuVRckeV5vl6QFQVGaZ5mWdZtmoEAA

πŸ’» Code

I don't know if it's strictly TypeScript issue or not (please let me know if I should report this elsewhere instead), but in v5.5.4 I noticed that type ComponentProps from React library doesn't work anymore when I use custom forwardRef (I use it so my generic components are typed correctly):

function forwardRef<T, P>(
  component: (props: P, ref: Ref<T>) => React.ReactNode,
): (props: P & { ref?: Ref<T> }) => React.ReactNode {
  return baseForwardRef(
    component as unknown as ForwardRefRenderFunction<unknown, unknown>,
  );
}

type ComponentWithForwardRefProps<T extends ElementType> =
  ComponentPropsWithoutRef<T> & {
    className?: string;
    as?: T | undefined;
  };

const ComponentWithForwardRef = forwardRef(
  <T extends ElementType = "span">(
    props: ComponentWithForwardRefProps<T>,
    ref: Ref<HTMLElement>,
  ) => {
    return null;
  },
);

type Result2 = ComponentProps<typeof ComponentWithForwardRef>["className"]; // error here: `className` cannot be used to index type etc.
let result2: Result2 = "some-class-name"; // error here, obvisously

When i remove the default value for type parameter T, it works again:

export const ComponentWithForwardRef = forwardRef(
  <T extends ElementType>(
    props: ComponentWithForwardRefProps<T>,
    ref: Ref<HTMLElement>,
  ) => {
    return null;
  },
);

type Result2 = ComponentProps<typeof ComponentWithForwardRef>["className"]; // Result2 is `string | undefined`

let result2: Result2 = "some-class-name"; // no error

It also works if I remove the as props:

type ComponentWithForwardRefProps<T extends ElementType> =
  ComponentPropsWithoutRef<T> & {
    className?: string;
  };

I'm not sure if this is a regression, or if I'm doing something wrong, but I would be grateful to get some more info on this. Thank you.

πŸ™ Actual behavior

Component props are not correctly inferred.

πŸ™‚ Expected behavior

Same as in previous version of TypeScript.

Additional information about the issue

No response

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions