How To Fix Styled Components Prop Types Issue In Typescript

3 min read

I have started using typescript in my react projects, at the beginning, it consumes lots of time to implement especially when we are not much familiar with typescript. But each minute we spend extra is a reward when a project grows.

Besides typescript, I use styled components for styling, because theming, conditional and reusable styling is easier in styled components.

Styled components take props and based on props we can define styling. In typescript, we have to define the types of each prop.

Recreating Error

Let's say we are building a reusable Button component in react, button accepts 3 props, title, variant, and onClick. Based on variant we define button background color, either primary or secondary.

import { FC } from 'react'
import styled from 'styled-components'
interface ButtonTypes {
title: string
variant?: 'primary' | 'secondary'
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
}
const ButtonStyle = styled.button`
padding: 12px 24px;
border: none;
outline: none;
border-radius: 8px;
font-size: 14px;
font-weight: 700;
cursor: pointer;
color: white;
background-color: ${({ variant }) =>
variant === 'primary' ? '#e8ae1b' : '#7d4b00'};
&:disabled {
background: #e7e8e9;
color: #9fa3a9;
cursor: not-allowed;
}
`
const Button: FC<ButtonTypes> = ({ title, onClick, variant = 'primary' }) => {
return (
<ButtonStyle type="button" onClick={onClick} variant={variant}>
{title}
</ButtonStyle>
)
}
export default Button

Styled Components Typescript Type Error

Typescript will keep yelling unless we define style types for variant.

Let's fix this

To fix this we define a separate type for our Button Style. It is exclusive to our button styles so we define it separately.

type StyleTypes = {
variant?: 'primary' | 'secondary'
}

then ButtonTypes extends StyleTypes

import { FC } from 'react'
import styled from 'styled-components'
type StyleTypes = {
variant?: 'primary' | 'secondary'
}
interface ButtonTypes extends StyleTypes {
title: string
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
}
const ButtonStyle = styled.button<StyleTypes>`
....
background-color: ${({ variant }) =>
variant === 'primary' ? '#e8ae1b' : '#7d4b00'};
....
`
const Button: FC<ButtonTypes> = ({ title, onClick, variant = 'primary' }) => {
return (
<ButtonStyle type="button" onClick={onClick} variant={variant}>
{title}
</ButtonStyle>
)
}
export default Button

Our Code editor is happy now.