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;
}
}
Answer from Sérgio Junior on Stack OverflowIt'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;
}
}
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.
I suppose you problem is in light-mode.tsx. How can i see you use typescript in that case need create a declarations file and DefaultTheme interface. example
Create a declarations file TypeScript definitions for styled-components can be extended by using declaration merging since version v4.1.4 of the definitions. documentation
light-mode.tsx
import { DefaultTheme } from 'styled-components';
export const lightTheme: DefaultTheme = {
colors: {
cardTitleColor: red;
}
};
I was looking for the same and found a solution for typing the theme object you receive as prop on your styled components.
First, export the types of your themes, e.g.:
export type LightTheme = typeof lightTheme;
Then add a src/declaration.d.ts file with the below, so to enhance the DefaultTheme exported by styled-components to be typed with your custom theme object:
import { Theme } from "globalStyles";
declare module "styled-components" {
export interface DefaultTheme extends Theme {}
}
From there you won't need any withTheme to use your theme object, as you will simply be able to access it through:
color: ${({theme}) => theme.colors.cardTitleColor};
Weird that you're having any for your theme typing.
I'm doing it in a close but different way:
styled-component.d.ts
// import original module declarations
import 'styled-components';
import { ITheme } from './styles/theme';
// and extend them!
declare module 'styled-components' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DefaultTheme extends ITheme {}
}
I'm extending DefaultTheme with my ITheme object, which is something like that:
import {
borderRadius,
boxShadows,
IBorderRadius,
IBoxShadows,
ITransitions,
IZIndexes,
transitions,
zIndexes,
} from './base';
import { colors, IColors } from './colors';
import { ISizes, sizes } from './sizes';
export interface ITheme {
colors: IColors;
sizes: ISizes;
boxShadows: IBoxShadows;
zIndexes: IZIndexes;
borderRadius: IBorderRadius;
transitions: ITransitions;
}
export const Theme: ITheme = {
colors,
sizes,
boxShadows,
zIndexes,
borderRadius,
transitions,
};
And I'm using <ThemeProvider> from import { ThemeProvider } from 'styled-components';
<ThemeProvider theme={Theme}>
I'm using nearly the same versions as you:
"styled-components": "^5.3.3",
"@types/styled-components": "^5.1.19",
And here is my tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"baseUrl": "src",
"paths": {
"~/*": ["./*"]
}
},
"include": [
"src"
]
}
In typescript, the type definition is very important.
1. theme
import {ThemeProvider} from 'styled-components';
<ThemeProvider theme={theme}>
//Your children component here
</ThemeProvider>
for types
//./styled-components.d.ts
import themeVariables from '<//theme variables path here>';
type ThemeInterface = typeof themeVariables
declare module "styled-components" {
interface DefaultTheme extends ThemeInterface {}
}
//tsconfig.json
{
"compilerOptions": {
"includes": ["styled-components.d.ts"]
}
}
After it, you can use the theme in the styled component
const SomeStyledComponent = styled.div`
background-color: ${props => props.theme.backgroundColor};
`
2.<{ invertedColor: boolean }> issue
interface SomeComponentProps {
invertedColor: boolean;
}
const SomeComponent = styled.div<SomeComponentProps>`
color: ${props => (props.invertedColor ? props.theme.color.white : props.theme.color.dark)}
`