Styled Components and TypeScript: No overload matches this call

Viewed 3446

I'm new to Style Components and I'm trying to build a weather app using React Native. I would normally use CSS modules but it seems that this isn't an option for mobile development.

Here's the code:

import ThemeModel from 'models/ThemeModel'
import React, { PureComponent } from 'react'
import styled from 'styled-components/native'

interface HomeScreenComponentInterface {
  theme?: ThemeModel
  getWeatherData: () => void;
  isLoading: boolean | null;
}

class HomeScreenComponent extends PureComponent<HomeScreenComponentInterface> {
  componentDidMount() {
    const { getWeatherData } = this.props

    getWeatherData()
  }

  render() {
    const Container = styled.View`
    padding: 20px 0;
  `
    const HeaderText = styled.Text`
    color: ${(props: HomeScreenComponentInterface) => props.theme && props.theme.colors.lightBlue};
    font-size: ${(props: HomeScreenComponentInterface) => props.theme && props.theme.fontSizes.xLarge};
    font-weight: 500;
  `
    return (
      <Container>
        <HeaderText>Weather App</HeaderText>
      </Container>
    )
  }
}

And here is a screen shot off the error:

overload error

Here's the Theme.tsx

import React, { FC, ReactNode } from 'react'
import { ThemeProvider } from 'styled-components'

const theme = {
  colors: {
    powderWhite: '#FFFDF9',
    persianGreen: '#06B49A',
    lightBlue: '#AFDBD2',
    onyx: '#36313D',
  },
  fonts: ['sans-serif', 'Roboto'],
  fontSizes: {
    small: '12px',
    medium: '16px',
    large: '24px',
    xLarge: '32px',
  },
}

interface ThemeProps {
  children: ReactNode
}

const Theme: FC<ThemeProps> = ({ children }) => (
  <ThemeProvider theme={ theme }>{children}</ThemeProvider>
)

export default Theme

I believe I only need to pass the theme props to this component, but I can't figure out how to do that..

Any help would be must appreciated.

3 Answers
interface HomeScreenComponentInterface {
  theme?: ThemeModel          // optional  
  getWeatherData: () => void; // required
  isLoading: boolean | null;  // required
}

No overload matched this call error is occurring because <HeaderText> is expecting the required properties according to the interface you have defined. Make them optional and it should work.

I was facing the same issue. Changing the prop values, defined in the interface, to optional? solved the problem for me.

Example with error:

interface CustomStyleProps {
     width: number;
     height: number;
};

const CarouselContainer = styled.div<CustomStyleProps>`
   display: flex;
   width: ${props => (props.width || 100) + `px`};
   height: ${props => (props.height || 100) + `px`};
`;
 
return(
     <CarouselContainer/> // Error : No overload matched this call
)

Example without error:

interface CustomStyleProps {
      width?: number;
      height?: number;
};
    
 const CarouselContainer = styled.div<CustomStyleProps>`
     display: flex;
     width: ${props => (props.width || 100) + `px`};
     height: ${props => (props.height || 100) + `px`};
 `;

 return(
     <CarouselContainer/> // No Error
 )
 const HeaderText = styled.Text`
     color: ${({ theme }) => theme.colors.lightBlue};
 `;

You don't have to include the theme's type in the props interface (HomeScreenComponentInterface). The ThemeProvider provides the theme to all styled components within its children. Typescript is throwing that error because you were telling the HeaderText styled component to expect the isLoading and getWeatherData props. These props are not necessary to render the styled component.

 const HeaderText = styled.Text<HomeScreenComponentInterface>`// Typescript magic
    color: ${({ theme }) => theme && theme.colors.lightBlue};
    `

Typescript is unable to infer the types for the props being passed to styled component, therefore you must explicitly set them as above.

Related