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.
1import { FC } from 'react'
2import styled from 'styled-components'
3
4interface ButtonTypes {
5 title: string
6 variant?: 'primary' | 'secondary'
7 onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
8}
9
10const ButtonStyle = styled.button`
11 padding: 12px 24px;
12 border: none;
13 outline: none;
14 border-radius: 8px;
15 font-size: 14px;
16 font-weight: 700;
17 cursor: pointer;
18 color: white;
19 background-color: ${({ variant }) => (variant === 'primary' ? '#e8ae1b' : '#7d4b00')};
20
21 &:disabled {
22 background: #e7e8e9;
23 color: #9fa3a9;
24 cursor: not-allowed;
25 }
26`
27
28const Button: FC<ButtonTypes> = ({ title, onClick, variant = 'primary' }) => {
29 return (
30 <ButtonStyle type="button" onClick={onClick} variant={variant}>
31 {title}
32 </ButtonStyle>
33 )
34}
35
36export default Button
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.
1type StyleTypes = {
2 variant?: 'primary' | 'secondary'
3}then ButtonTypes extends StyleTypes
1import { FC } from 'react'
2import styled from 'styled-components'
3
4type StyleTypes = {
5 variant?: 'primary' | 'secondary'
6}
7
8interface ButtonTypes extends StyleTypes {
9 title: string
10 onClick: (event: React.MouseEvent<HTMLButtonElement>) => void
11}
12
13const ButtonStyle = styled.button<StyleTypes>`
14 ....
15 background-color: ${({ variant }) => (variant === 'primary' ? '#e8ae1b' : '#7d4b00')};
16
17 ....
18`
19
20const Button: FC<ButtonTypes> = ({ title, onClick, variant = 'primary' }) => {
21 return (
22 <ButtonStyle type="button" onClick={onClick} variant={variant}>
23 {title}
24 </ButtonStyle>
25 )
26}
27
28export default ButtonOur Code editor is happy now.
Written by
Abdul Basit
Frontend developer passionate about JavaScript, React, and building great web experiences. Writing about web development to help developers level up their skills.
Continue reading