Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StyledComponents with Typescript and ThemeProvider. What are the right types?

I have problems to get the right types when using StyledComponents with ThemeProvider.

I have tried it with this approach: https://github.com/styled-components/styled-components/issues/1589

My code so far:

App.tsx

import * as React from "react";
import "./styles.css";
import theme from "./theme";
import { ThemeProvider } from "styled-components";
import StyledButton from "./StyledButton";

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <div className="App">
        <StyledButton variant="primary">MyButton</StyledButton>
      </div>
    </ThemeProvider>
  );
}

theme.ts

import "styled-components";
const theme = {
  borderRadius: "0.7rem",
  color: "yellow"
};

export default theme;

StyledButton.tsx

import styled from "styled-components";

interface IButtonProps {
  color: string;
  backgroundColor: string;
  borderRadius?: string;
}

const buttonProps = (props: any): IButtonProps => {
  /* defaultValues / primary */
  let bp: IButtonProps = {
    color: props.theme.color,
    backgroundColor: "#2862c3c4"
  };

  if (props.variant === "primary") {
    return bp;
  } else if (props.variant === "secondary") {
    bp.color = "white";
    bp.backgroundColor = "#808080c2";
  }

  return bp;
};

const StyledButton = styled.button<IButtonProps>`
  color: ${props => (props.color ? props.color : buttonProps(props).color)};
  background-color: ${props =>
    props.backgroundColor
      ? props.backgroundColor
      : buttonProps(props).backgroundColor};
  border-radius: ${props => props.theme.borderRadius};
`;

export default StyledButton;

styled-components.d.ts

import theme from "./globals/theme";

type CustomTheme = typeof theme;

declare module "styled-components" {
  export interface DefaultTheme extends CustomTheme {}
}

So what do I have to change to get rid of the any type in:

const buttonProps = (props: any): IButtonProps

and the ts warning for variant in:

<StyledButton variant="primary">MyButton</StyledButton>

Example is here:
https://codesandbox.io/embed/styledcomponents-typescript-zut79?fontsize=14&hidenavigation=1&theme=dark

like image 254
mardro Avatar asked Jul 22 '20 08:07

mardro


1 Answers

It's described in the official documentation.

In a .d.ts file add this:

import 'styled-components';

declare module 'styled-components' {
  export interface DefaultTheme {
     borderRadius: string;
     color: string;
  }
}

like image 115
Sérgio Junior Avatar answered Sep 23 '22 06:09

Sérgio Junior