Reputation: 6961
I can't find a way to make Emotion theming work with TypeScript.
import React from "react";
import { ThemeProvider } from "emotion-theming";
import styled from "@emotion/styled";
const theme = {
colors: {
gray: "#ccc",
},
};
const MyComponent = styled.div((props) => ({
color: props.theme.colors.gray,
}));
const App = () => (
<ThemeProvider theme={theme}>
<MyComponent />
</ThemeProvider>
);
export default App;
The docs says: "By default, props.theme has an any type annotation and works without any errors". But I have one on props.theme.colors.gray
: Property 'colors' does not exist on type 'object'.ts(2339)
Am I missing something here?
Upvotes: 9
Views: 5264
Reputation: 4074
Continuing on @chatian's helpful answer, after you've made the .d.ts file, then put it somewhere in your project, e.g., in the "src" folder, and specify it as an "ambient file" to be used by the TS runtime of your editor by adding its directory path, i.e. "src"
, in the "include"
array of your tsconfig.json
file.
Now you should be able to use both your own types and import the types you extend from emotion in your tsx files, e.g., import { Theme } from "@emotion/react"
.
An example codesandbox: https://codesandbox.io/s/9z2md?file=/src/global.d.ts
Notice since the Theme type in the above example is not "extending" emotion's Theme type then you don't need to import it at all and you have access to it globally.
(note: this sandbox was not created by me so credit goes to nerdyman.)
Upvotes: 2
Reputation: 22984
Emotion 11 simplified this.
Define your Theme in an emotion.d.ts
file
declare module '@emotion/react' {
export interface Theme {
colors : {
primary: string;
secondary: string;
};
}
}
This provides an override for the empty Theme
interface within Emotion.
https://emotion.sh/docs/typescript#define-a-theme
Upvotes: 8