Reputation: 14768
I'm writing a React app using TypeScript. I use material-ui for my components. I'm writing a custom wrapper for material-ui's Button component. It looks like this:
import MUIButton, { ButtonProps } from "@material-ui/core/Button";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import classNames from "classnames";
import React, { PureComponent } from "react";
import styles from "./styles";
export interface OwnProps {
color: "primary" | "danger" | "warning" | "transparent";
size: "sm" | "lg";
}
export interface Props
extends WithStyles<typeof styles>,
OwnProps,
ButtonProps {}
export class Button extends PureComponent<Props> {
render() {
const { color, size, classes, children, ...rest } = this.props;
const btnClasses = classNames({
[classes.button]: true,
[classes[size]]: size,
[classes[color]]: color
});
return (
<MUIButton {...rest} className={btnClasses}>
{children}
</MUIButton>
);
}
}
export default withStyles(styles)(Button);
The problem is that here that the definition of Props throw the error message:
Named property 'color' of types 'OwnProps' and 'ButtonProps' are not identical.
[ts]
Interface 'Props' cannot simultaneously extend types 'OwnProps' and 'ButtonProps'.
Named property 'size' of types 'OwnProps' and 'ButtonProps' are not identical.
Named property 'color' of types 'OwnProps' and 'ButtonProps' are not identical.
[ts]
Interface 'Props' cannot simultaneously extend types 'OwnProps' and 'ButtonProps'.
Named property 'size' of types 'OwnProps' and 'ButtonProps' are not identical.
This error goes away if I instead write:
export class Button extends PureComponent<Props & ButtonProps> {
But then when using the Button the props color and size throw the error:
The expected type comes from property 'color' which is declared here on type 'IntrinsicAttributes & Pick<Props & ButtonProps, ...
How can I correctly tell the component that it has the the Props I defined (OwnProps
) as well as the props that come from the Button as usual?
Upvotes: 16
Views: 22708
Reputation: 2721
Use TypeScript's Omit
type to exclude specific properties from another type:
Constructs a type by picking all properties from Type and then removing Keys (string literal or union of string literals).
import { ButtonProps } from "@material-ui/core/Button";
export type OwnProps = Omit<ButtonProps, "color" | "size"> & {
color: "primary" | "danger" | "warning" | "transparent";
size: "sm" | "lg";
}
class MyButton extends React.Component<OwnProps> {
}
Upvotes: 23