Extending HTML elements in React and TypeScript while preserving props

Solution 1:

You can change the definition of your component to allow the react html button props

class MyButton extends React.Component<MyButtonProps & React.HTMLProps<HTMLButtonElement>, {}> {
    render() {
        return <button {...this.props}/>;
    }
}

That will tell the typescript compiler that you want to enter the button props along with 'MyButtonProps'

Solution 2:

Seems Like the above answer is outdated.

In my case I'm wrapping a styled component with a functional component, but still want to expose regular HTML button properties.

export const Button: React.FC<ButtonProps &
  React.HTMLProps<HTMLButtonElement>> = ({
  ...props,
  children,
  icon
}) => (
  <StyledButton {...props}>
    {icon && <i className="material-icons">{icon}</i>}
    {children}
  </StyledButton>
);

Solution 3:

I always like to do it this way:

import React from 'react';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  title: string;
  showIcon: boolean;
}

const Button: React.FC<ButtonProps> = ({ title, showIcon, ...props }) => {
  return (
    <button {...props}>
      {title}
      {showIcon && <Icon/>}
    </button>
  );
};

Then you can do:

<Button
  title="Click me"
  onClick={() => {}} {/* You have access to the <button/> props */}
/>