Reputation: 517
I had this following code for the PropTypes of my button styled component
export type Props = {
size?: 'small' | 'medium' | 'large',
};
StyledButton.defaultProps = {
size: 'medium',
};
It was working fine but then I wanted to include HTMLButtonElement props to provide interactivity to my button. Therefore I added this:
export type Props = React.HTMLProps<HTMLButtonElement> & {
size?: 'small' | 'medium' | 'large',
};
StyledButton.defaultProps = {
size: 'medium',
};
However, this change makes defaultProps complains. This is the error, I am getting.
Types of property 'size' are incompatible.
Type 'string' is not assignable to type 'undefined'.ts(2322)
However, If I take away the React.HTMLProps, it works, but that's not what I want. Does anybody know a solution for this?
Thanks in advance.
Upvotes: 3
Views: 5571
Reputation: 7204
The HTMLProps
type already includes a size
.
I recommend using ButtonHTMLAttributes
instead:
type Props = React.ButtonHTMLAttributes<HTMLButtonElement> & {
size?: 'small' | 'medium' | 'large',
};
Upvotes: 0
Reputation: 4957
I also found that simply extending React.HTMLProps<HTMLButtonElement>
does not work if you want to set custom value for size
prop. Here's a solution for this problem. We're going to need
small helper called Omit
from utility-types
package (https://github.com/piotrwitek/utility-types#omitt-k)
And use it like this:
import { Omit } from 'utility-types';
type BaseButtonProps = Omit<React.HTMLProps<HTMLButtonElement>, 'size'>;
interface ButtonProps {
size?: 'lg' | 'sm';
}
const Button: React.FC<ButtonProps & BaseButtonProps> = ({ size }) => {
// size is now 'lg', 'sm' or undefined
};
Upvotes: 3
Reputation: 130162
I think you have to define a new interface:
export interface Props extends React.HTMLProps<HTMLButtonElement> {
size?: 'small' | 'medium' | 'large',
};
The problem is that React.HTMLProps
or rather, its superinterface HTMLAttributes
already contains a size
attribute defined as:
size?: number;
Therefore, you will have to rename your property.
Upvotes: 6
Reputation: 5977
So try these, as I looked at the site https://medium.com/@martin_hotell/react-typescript-and-defaultprops-dilemma-ca7f81c661c7
type Props = Partial<DefaultProps>;
type DefaultProps = Readonly<typeof defaultProps>;
const defaultProps = {
size: 'small' as 'small' | 'medium' | 'large';
};
export YourClass extends React.Component<Props> { }
That is the simplest easiest way, perhaps, of solving your issue, although there are others there that might help if that doesn't.
Upvotes: 0