Definitelytyped: [@types/react] button refuses its own props

Created on 28 Jun 2019  路  6Comments  路  Source: DefinitelyTyped/DefinitelyTyped

  • [x] I tried using the @types/react package and had problems.
  • [x] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [x] I have a question that is inappropriate for StackOverflow. (Please ask any appropriate questions there).
  • [x] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @ferdaber @lukyth @DovydasNavickas

const Button = (props: React.HTMLProps<HTMLButtonElement>) => (
  <button {...props} />
);
error TS2322: Type '{ accept?: string | undefined; acceptCharset?: string | undefined; action?: string | undefined; allowFullScreen?: boolean | undefined; allowTransparency?: boolean | undefined; alt?: string | undefined; ... 353 more ...; key?: string | ... 1 more ... | undefined; }' is not assignable to type 'DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>'.
  Type '{ accept?: string | undefined; acceptCharset?: string | undefined; action?: string | undefined; allowFullScreen?: boolean | undefined; allowTransparency?: boolean | undefined; alt?: string | undefined; ... 353 more ...; key?: string | ... 1 more ... | undefined; }' is not assignable to type 'ButtonHTMLAttributes<HTMLButtonElement>'.
    Types of property 'type' are incompatible.
      Type 'string | undefined' is not assignable to type '"button" | "reset" | "submit" | undefined'.
        Type 'string' is not assignable to type '"button" | "reset" | "submit" | undefined'.

   <button {...props} />
    ~~~~~~


Found 1 error.

Most helpful comment

HTMLProps is the common set all attributes that _every_ HTML element can possibly have, so actually there's another interface called ButtonHTMLAttributes that have button-specific props. In the specific case of this issue, ButtonHTMLAttributes narrows the type of the type attribute even further to just an enumeration of those string literals ('submit' | 'button' rather than just the general string type).

So React.HTMLProps<HTMLButtonElement> is not sufficient to describe the set of attributes that an HTML button element can have. The proper (and easiest) solution is to just use ComponentProps<'button'> which automatically seeks the most appropriate interface you need for a host element.

All 6 comments

I think what you're probably looking for is React.HTMLAttributes<HTMLButtonElement>.

Jake has it right. It might even be easier to do JSX.IntrinsicElements['button'] for easier memorization.

I had the most success using React.ComponentProps<'button'> - using HTMLAttributes meant the disabled prop was missing for some reason

So is React.ComponentProps<'button'> a workaround (or the official solution)? or is React.HTMLProps<HTMLButtonElement> "broken"?

HTMLProps is the common set all attributes that _every_ HTML element can possibly have, so actually there's another interface called ButtonHTMLAttributes that have button-specific props. In the specific case of this issue, ButtonHTMLAttributes narrows the type of the type attribute even further to just an enumeration of those string literals ('submit' | 'button' rather than just the general string type).

So React.HTMLProps<HTMLButtonElement> is not sufficient to describe the set of attributes that an HTML button element can have. The proper (and easiest) solution is to just use ComponentProps<'button'> which automatically seeks the most appropriate interface you need for a host element.

In my case, type of the props was almost likely incorrect after partially spreading these props.

export const Button: Overload = ({
  color = 'primary',
  className,
  href,
  ...rest
}: ButtonProps | AnchorProps) => {
    // here, in ...rest, "type" property of the button will be "string | undefined".
}

So I had to force the rest-spreaded props like this:

<button className={clx} style={style} {...rest as ButtonProps}>
    {children}
</button>
Was this page helpful?
0 / 5 - 0 ratings