Reputation: 989
I am trying to create a button component using styled components that takes a prop as
which can be a ComponentType | string
When I try another prop called skin
or size
I get the error No overload matches this call
. I have googled what I can think of under the sun. I have tried everything I could. I initially didn't use the attrs
in styled components but after googling for hours I think I need to use it but not sure. What am I missing?
Here is the Button component:
const Button: FunctionComponent<FullProps> = ({
as,
children,
skin = "primary",
size = "medium",
...props,
}) => {
return (
<Component
as={as}
size={size}
skin={skin}
{...props}
>
{children}
</Component>
);
};
Here is the type FullProps
which has all of the props but I'm trying reduce it to the smallest issue:
export type FullProps = {
as?: ComponentType | string;
isFullWidth?: boolean;
disabled?: boolean;
shadow?: ShadowStep;
size?: Size;
skin?: Skin;
theme?: Theme;
type?: HtmlButtonType;
href?: string;
onClick?: () => void;
children?: ReactNode;
id?: string;
loadingConfig?: LoadingConfig;
icon?: IconConfig;
};
I know when using styled components you should use the prop forwardedAs
to pass a as
value down. That part works if I just have a simple component that takes as:
const DemoALink = styled(Button)`
color: white;
background: #fb6058;
height: 4rem;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
`;
Here is the styled component being used:
<DemoALink forwardedAs="a" skin="primary">
Testings
</DemoALink>
And this is the styling for the component:
export const Button = styled.button.attrs<FullProps>(
({ disabled, as, type }: FullProps) => ({
type: as === "button" && type ? type : undefined,
disabled,
})
// )<Required<FullProps> & { children: ReactNode }>`
)<Required<FullProps> & { children: ReactNode }>`
${baseStyles};
${({ skin, theme }) => getVariant({ skin, theme })}
padding-top: ${getHeight};
padding-bottom: ${getHeight};
box-shadow: ${shadow};
width: ${({ isFullWidth }: { isFullWidth: boolean }) =>
isFullWidth ? "100%" : "auto"};
`;
Upvotes: 1
Views: 4375
Reputation: 66
I recently ran into this same error while trying to use typescript in styled components. I eventually resolved it and found out the reason I was having that error. I'll sight an example for context.
imagine declaring a type for an avatar component like so:
interface Avatar {
src?: string,
alt: string,
height: string,
width: string,
}
It would be safe to make use of this type declaration in the desired component like so:
const AvatarContainer: FC<Avatar> = ({src, alt, width, height}) => {
return (
<Container width={width} height={height}>
<img src={src} alt={alt} />
</Container>
)
};
export default AvatarContainer;
const Container = styled.div<{width: string, height: string}>`
width: ${(props) => props.width || '35px'};
height: ${(props) => props.height || '35px'};
overflow: hidden;
border-radius: 50%;
`;
Note that the above will work correctly without erroring out. However, to reproduce the
no overload matches this call
error, let's modify the above jsx to:
const AvatarContainer: FC<Avatar> = ({src, alt, width, height}) => {
return (
<Container width={width} height={height}>
<img src={src} alt={alt} />
</Container>
)
};
export default AvatarContainer;
const Container = styled.div<Avatar>`
width: ${(props) => props.width || '35px'};
height: ${(props) => props.height || '35px'};
overflow: hidden;
border-radius: 50%;
`;
The above will error out. This is because the type definition 'Avatar' contains two more props, src and alt that our Container component does not need. What we want to do instead, is specify explicitly the props that our Container component needs as outlined in our first code example.
I hope this was helpful.
Upvotes: 1
Reputation: 1
Here is how I resolved a No overload matches this call
error in my styled-component:
interface Props{
someProp: string
}
const SomeStyledComponent = styled.div<{ someProp: string}>`
some-css-property: ${(props) => props.someProp}
`
export default function SomeCompnent({ someProp }: Props): ReactElement{
return(
<SomeStyledComponent someProp={someProp} />
)
}
Upvotes: 0