Published on

Fixing 'Prop Does Not Exist' Issue in Styled-Components with TypeScript

Authors
  • Name
    Ripal & Zalak
    Twitter

Fixing 'Prop Does Not Exist' Issue in Styled-Components with TypeScript

When working with styled-components and TypeScript, you may encounter an error stating:

Property 'emphasized' does not exist on type 'ThemedStyledProps...'.

This happens because TypeScript does not automatically infer additional props in styled-components. Below, we'll discuss how to fix this issue.

The Problem

Consider the following React component using styled-components:

import * as React from 'react'
import styled from 'styled-components'
import { ComponentChildren } from 'app-types'

interface Props {
  children: ComponentChildren
  emphasized: boolean
}

const HeadingStyled = styled.h2`
  ${(props) =>
    props.emphasized &&
    `
        display: inline;
        padding-top: 10px;
        padding-right: 30px;
    `}
`

const Heading = (props: Props) => <HeadingStyled>{props.children}</HeadingStyled>

export default Heading

This results in a TypeScript error because emphasized is not recognized within styled.h2.

Solution: Define Prop Types Correctly

To fix this, explicitly define the prop types for the styled component:

import * as React from 'react'
import styled, { css } from 'styled-components'
import { ComponentChildren } from 'app-types'

interface Props {
  children: ComponentChildren
  emphasized: boolean
}

const HeadingStyled = styled.h2<{ emphasized: boolean }>`
  ${({ emphasized }) =>
    emphasized &&
    css`
      display: inline;
      padding-top: 10px;
      padding-right: 30px;
    `}
`

const Heading: React.FC<Props> = ({ children, emphasized }) => (
  <HeadingStyled emphasized={emphasized}>{children}</HeadingStyled>
)

export default Heading

Key Fixes

Explicitly define the prop type: styled.h2<{ emphasized: boolean }>

Pass emphasized prop: <HeadingStyled emphasized={emphasized}>

Import css from styled-components: This helps in conditional styling.

Alternative Approach Using Interface

If you prefer, you can use an interface to define props:

interface HeadingProps {
  emphasized: boolean
}

const HeadingStyled = styled.h2<HeadingProps>`
  ${({ emphasized }) =>
    emphasized &&
    css`
      display: inline;
      font-weight: bold;
    `}
`

Common FAQs

1. Why does TypeScript not recognize my styled-component props?

TypeScript does not automatically infer custom props in styled-components. You must explicitly define them using <{propType}>.

2. How do I pass multiple props?

You can extend the interface:

const HeadingStyled = styled.h2<{ emphasized: boolean; size?: string }>`
  ${({ emphasized, size }) =>
    emphasized &&
    css`
      font-size: ${size || '16px'};
    `}
`

3. What if my styles are not applying?

Ensure you are passing props correctly in both the styled-component and its parent component.