Extending HTML elements in React and TypeScript wh

2020-05-24 20:38发布

问题:

I just can't wrap my head around this I guess, I've tried probably half a dozen times and always resort to any... Is there a legitimate way to start with an HTML element, wrap that in a component, and wrap that in another component such that the HTML props pass through everything? Essentially customizing the HTML element? For example, something like:

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

interface MyAwesomeButtonProps extends MyButtonProps {}
class MyAwesomeButton extends React.Component<MyAwesomeButtonProps, {}> {
    render() {
        return <MyButton/>;
    }
}

Usage:

<MyAwesomeButton onClick={...}/>

Whenever I attempt this sort of composition, I get an error similar to:

Property 'ref' of foo is not assignable to target property.

回答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'



回答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.ButtonHTMLAttributes<HTMLButtonElement>> = ({ children, icon, ...props}) => ( 
  <StyledButton { ...props}>
     { icon && (<i className = "material-icons" >{icon}< /i>)} 
     {children} 
   </StyledButton>);