emotion: CSS prop incompatible with typescript

  • emotion version: 9.1.3
  • react version: 16.4.0
  • react-emotion: 9.1.3
  • react-app-rewire-emotion: 4.0.0
  • babel-plugin-emotion: 9.1.2
  • @types/react: 16.3.4
  • @types/react-dom: 16.0.5

Relevant code.

class App extends Component {
  render() {
    return (
      <div
        className="App"
        css={`
          color: pink;
        `}
      >
        <p>hello world</p>
      </div>
    )
  }
}

What you did:

try to compile App.tsx

What happened:

Compilation error:

TS2339: Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
No lint errors found
Version: typescript 2.8.3, tslint 5.10.0

Problem description:

Typescript doesn’t understand css prop.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 14
  • Comments: 34 (19 by maintainers)

Commits related to this issue

Most upvoted comments

React 17 with Typescript 4.2 and Emotion.js 11.1 setup

Just add the following line to react-app-env.d.ts as stated in https://emotion.sh/docs/emotion-11 /// <reference types="@emotion/react/types/css-prop" />

and import with

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'

in tsconfig.json make shure to have "jsx": "react-jsx"

If anyone is having trouble with getting this to work, nuking node_modules and my yarn.lock resolved all my issues with the css prop. Found this here: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/21242.

Not ideal, but it does the job.

I had to add react-emotion to the types array in my tsconfig.json: (it works with emotion and create-emotion aswell)

"types": ["node", "react-emotion"]

for the addition of the css prop/attribute to the HTMLAttributes interface to be included: https://github.com/emotion-js/emotion/blob/v9.2.8/packages/create-emotion/types/index.d.ts#L94-L98

The TypeScript workflow could be simplified by providing a @types/emotion-core package through DefinitelyTyped, containing type augmentations without having to override types in tsconfig.json. @emotion/core could add @types/emotion-core as a dependency for fluid, zero-config developer experience.

I was trying to figure out this issue in relation to a simple app created with https://github.com/zeit/next.js (awesome package btw!)

(note this wasn’t failing the build, but just complaining in VSCode)

After much fumbling it seemed somehow to a separate install of @types/react under @types/next/node_modules. Since @types/react was already under my main folder’s node_modules, I didn’t feel adding it was required. But by hovering over a declare module ‘react’ reference, I saw it was pointing to this underlying node_modules folder.

TLDR: By doing

yarn add @types/react

it fixed the problem, seemingly so that @types/next could just point to the version already installed by @types/react in package.json (educated guess), so it didn’t add any additional install

Couldn’t reproduce after this, but hope this helps someone 😉

@kentcdodds Oh, I just realized, your "types" are in the wrong object. It’s not top-level, it should be inside "compilerOptions".

(also, I’d suggest using esModuleInterop and import React from 'react' instead, because 'react' is not a real ES module)

That would automatically make any @types package you install (directly or indirectly) that has global declarations make them available to your code.

I personally avoid it (even giving types: [] on some packages) but if you want to keep the behavior, then you can remove the types array and just add a /// <reference types="@emotion/core"/> or import {} from '@emotion/core' anywhere in your project (even in a .d.ts file that is caught by your includes). TypeScript elides import {} from as being a type-only import (as in, you made no use of any concrete values from the import).

You’re augmenting the wrong thing (rather, the compiler’s JSX support is weird in a lot of ways and the only sensible thing to augment that works with both intrinsic and non-intrinsic components is this).

The augmentation you are looking for is 'react''s Attributes.

declare module 'react' {
  interface Attributes {
    css?: InterpolationWithTheme<any>
  }
}

This definition now lives in the core package — so the entry in tsconfig.json should say "@emotion/core" instead of "react-emotion".

https://github.com/emotion-js/emotion/blob/34031439e084d68fa610b8491163618352fa9b97/packages/core/types/index.d.ts#L84-L88

Interesting. Thank you for sharing that @Kovensky! You’ve been very helpful to me tonight (both here and on twitter! 🙏)

Fantastic, thank you so much @Kovensky! That solved it for me ❤️

So I’m a bit put off by this solution because of this note in the docs:

This tsconfig.json file will only include ./node_modules/@types/node, ./node_modules/@types/lodash and ./node_modules/@types/express. Other packages under node_modules/@types/* will not be included.

I feel like it would be nice to not have to keep this list updated and just auto-include all the node_modules/@types definitions. Am I unnecessarily concerned?

I’m working with a monorepo built using yerna and @barrymay 's answer was the solution for me