5

I would like to extend the default Material-UI button to add more variants such as "square."

How can I define the prop interface to inherit/combine props.

Here's my code:

import React from "react";
import { Button as MuiButton } from "@material-ui/core";
import { ButtonProps as MuiButtonProps } from "@material-ui/core/Button";

interface ButtonProps extends MuiButtonProps {
  variant?: "square";
}

const defaultProps = {};

const Button: React.FC<ButtonProps> = ({variant, children, ...props}) => {
  return (
    <MuiButton variant={variant} {...props}>
       {props.children}
    </MuiButton>;
  )
};

Button.defaultProps = defaultProps;

export default Button;

Ideally, I would like to use this component like so:

<ExtendedButton href="/" variant="square">Click Me!</ExtendedButton>
Moussa Harajli
  • 1,486
  • 5
  • 22
  • 36

1 Answers1

4

The TYpeScript does not allows to override property when extending interfaces. So you should firstly exclude property from MuiButtonProps and then redefine it in ButtonProps.

import React from "react";
import { Button as MuiButton } from "@material-ui/core";
import { ButtonProps as MuiButtonProps } from "@material-ui/core/Button";

interface ButtonProps extends Pick<MuiButtonProps, Exclude<keyof MuiButtonProps, "variant">> {  
    variant?: "square" | MuiButtonProps["variant"];
}

Property exclusion with Pick and Exclude is for TypeScript 3.5 and below to 2.8. You may see another options to exclude properties depending on TypeScript version you use.

And as you wish to extend current type of existing property variant, you can use index access operator to get type of original variant property to union it with additional "square" type.

Fyodor Yemelyanenko
  • 11,264
  • 1
  • 30
  • 38
  • This will not work, the variant property defined in MuiButtonProps is defined as: variant?: "text" | "outlined" | "contained". I would like to extend these props and add "square" as an option for my new component. – Moussa Harajli Jun 21 '19 at 16:22
  • I've modified answer. Take a look please – Fyodor Yemelyanenko Jun 22 '19 at 10:19
  • When you pass the incoming prop that may include variant: "square" to the MuiButton, it will throw an error, right? Since it doesn't know "square". How do you filter out properties to match the type definition to a Mui component implementation that you are extending? – Marc Oct 28 '21 at 11:49