'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
Solution 1:[1]
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;
}
}
Solution 2:[2]
Add as const
to your theme object like this.
const theme = {
borderRadius: "0.7rem",
color: "yellow"
} as const;
Solution 3:[3]
Inside your src folder, create a new folder named @types and put your file styled.d.ts inside this folder. The content is the same as below.
import 'styled-components';
import theme from "your_theme_path";
type CustomTheme = typeof theme;
declare module "styled-components" {
export interface DefaultTheme extends CustomTheme {}
}
It has worked for me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sérgio Junior |
Solution 2 | Nathnael Dejene |
Solution 3 | pablojmde |