I have a functional component like so:
import React, { memo } from 'react';
import {
ButtonStyled,
LinkStyled,
Text,
} from './index.style';
export interface Props {
buttonType?: string;
handleClick?: () => void;
href?: string;
invertColors?: boolean;
isDisabled?: boolean;
isLoading?: boolean;
text: string;
variant?: 'dark' | 'light';
}
const defaultProps = {
buttonType: 'button',
handleClick: null,
href: null,
invertColors: false,
isDisabled: false,
isLoading: false,
variant: 'dark',
};
const Button = ({
buttonType,
handleClick,
href,
isDisabled,
isLoading,
text,
variant,
}: Props) => {
if (href) {
return (
<LinkStyled
href={href}
isDisabled={isDisabled}
isLoading={isLoading}
variant={variant}
>
<Text isLoading={isLoading}>
{text}
</Text>
</LinkStyled>
);
}
return (
<ButtonStyled
disabled={isDisabled}
isDisabled={isDisabled}
isLoading={isLoading}
onClick={handleClick}
type={buttonType}
variant={variant}
>
<Text isLoading={isLoading}>
{text}
</Text>
</ButtonStyled>
);
};
Button.defaultProps = defaultProps;
export default memo(Button);
There is a single Typescript error in this file and it's to do with the line type={buttonType}
. The error is:
Type 'string | undefined' is not assignable to type '"button" | "reset" | "submit" | undefined'.
I understand this error. React types have declared the 'type' attribute must be either 'button', 'reset', 'submit' or 'undefined' but I have set my props to be either string or undefined.
My question is, how do I assign the options from React to my props to avoid duplication by typing out all the options manually?
EDIT: The full error here:
Type 'string | undefined' is not assignable to type '"button" | "reset" | "submit" | undefined'.
Type 'string' is not assignable to type '"button" | "reset" | "submit" | undefined'.ts(2322)
index.d.ts(1849, 9): The expected type comes from property 'type' which is declared here on type 'IntrinsicAttributes & Pick<Pick<Pick<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "form" | "style" | "title" | "className" | "color" | ... 259 more ... | "value"> & { ...; } & ButtonStyledProps, "isDisabled" | ... 267 more ... | "value"> & Partial<...>, "isDisabled" | ... 267 more ....'
The type in question from @types/react looks like this:
interface ButtonHTMLAttributes<T> extends HTMLAttributes<T> {
autoFocus?: boolean;
disabled?: boolean;
form?: string;
formAction?: string;
formEncType?: string;
formMethod?: string;
formNoValidate?: boolean;
formTarget?: string;
name?: string;
type?: 'submit' | 'reset' | 'button';
value?: string | string[] | number;
}
Pick
e.g.type ButtonType = Pick<ButtonHTMLAttributes<any>, 'type'>;
– Mosh FeuPick
could probably be used so extract a object type that only containstype
, here the OP needs to use the type in the type ofbuttonType
. – Titian Cernicova-Dragomir