webdif
webdif

Reputation: 6961

Emotion theming with TypeScript: Property 'X' does not exist on type 'object'. ts(2339)

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

Answers (2)

aderchox
aderchox

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

cgatian
cgatian

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

Related Questions