Skip to content

Arguments to callback prop of generic React component are not inferred #44596

@Mesoptier

Description

@Mesoptier

Bug Report

🔎 Search Terms

react, polymorphic components, generic components, type inference on function arguments

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about type inference on function arguments

⏯ Playground Link

Playground link with relevant code

💻 Code

import React from 'react';

type Props<T extends React.ElementType> =
  { as: T } & Omit<React.ComponentPropsWithoutRef<T>, 'as'>;

declare function Button<T extends React.ElementType>(props: Props<T>): JSX.Element;

// Using Button as React component (intended use case):

// OK: The type of `Button` is `function Button<"button">(props: Props<"button">): JSX.Element` in this instance.
<Button
  as="button"
  // OK: The type of `onClick` is `(JSX attribute) onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined`.
  // NOT OK: The type of `e` is `any` (implicitly).
  onClick={(e) => { console.log(e); }}
/>;

// Using Button as regular function (same issue):

// OK: The type of `Button` is `function Button<"button">(props: Props<"button">): JSX.Element` in this instance.
Button({
  as: 'button',
  // OK: The type of `onClick` is `(property) onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined`.
  // NOT OK: The type of `e` is `any` (implicitly).
  onClick: (e) => { console.log(e); },
});

🙁 Actual behavior

The argument e to the callback function provided to onClick implicitly has any type.

🙂 Expected behavior

I would expect the checker to know that the type of e can only be React.MouseEvent<HTMLButtonElement, MouseEvent>.

The checker seems to know that the type of the onClick callback is React.MouseEventHandler<HTMLButtonElement>, which in turn resolves to (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void. So I would expect the checker to be able to use that information to determine the type of e / event.

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