Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TS2322: 'css' does not exist on type 'DetailedHTMLProps...' with new JSX runtime w/ NextJs #2111

Closed
clfhhc opened this issue Nov 17, 2020 · 11 comments

Comments

@clfhhc
Copy link

clfhhc commented Nov 17, 2020

Current behavior:
I have used NextJs v10.0.1 and emotionJs v11.0.0. I installed the @emotion/babel-plugin and followed the new jsx runtime setup with NextJs in this page.

{
  "presets": [
    [
      "next/babel",
      {
        "preset-react": {
          "runtime": "automatic",
          "importSource": "@emotion/react"
        }
      }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}

I still get errors when input css properties in the JSX react element.

(JSX attribute) css: SerializedStyles
Type '{ children: Element[]; css: SerializedStyles; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
  Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.ts(2322)

To reproduce:

  1. clone this repo: https://github.com/Project-Setup/Nextjs_Ts_Eslint
  2. run script in the project folder
nvm use || nvm install
npm install
npm run build
  1. get an error on the build step
> [email protected] build
> next build

Failed to compile.

./src/pages/index.tsx:21:12
Type error: Type '{ children: Element; css: SerializedStyles; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.
  Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.

  19 |     <div>
  20 |       <Global styles={globalBodyStyles} />
> 21 |       <div css={indexPageStyles}>
     |            ^
  22 |         <h1 css={titleStyles}>Project Setup</h1>
  23 |       </div>
  24 |     </div>
info  - Creating an optimized production build .npm ERR! code 1

Expected behavior:
Babel should map css properties in JSX elements and typescript should not output type error TS2322 for css in JSX elements.

Environment information:

  • react version: 17.0.1
  • @emotion/react version: 11.0.0
  • nextjs version: 10.0.1
  • typescript: 4.0.5
@Andarist
Copy link
Member

#2106 (comment)

@clfhhc
Copy link
Author

clfhhc commented Nov 17, 2020

#2106 (comment)

I read that comment and was following the New JSX runtime and babel-plugin/preset setup, and TS is most updated. (They are listed in the issue description.)

I read this note too, so that's why I did not install the @emotion/babel-preset-css-prop
截图录屏_选择区域_20201117001424

@Andarist
Copy link
Member

For the JSX namespace to be resolved automatically with the new automatic runtime you need to be on TS 4.1 which is supposed to be released this week. This is mentioned in that linked post:

For the automatic runtime this has been implemented by exporting JSX namespace from the appropriate entries but this is only supported in TypeScript 4.1 or higher.

There is also mentioned an intermediary solution of adding /// <reference types="@emotion/react/types/css-prop" /> to your project.

@clfhhc
Copy link
Author

clfhhc commented Nov 17, 2020

So I have to update the TS version to 4.1 to make use of the new JSX runtimes. Gotcha, thanks.

@clfhhc clfhhc closed this as completed Nov 17, 2020
@clfhhc clfhhc reopened this Nov 24, 2020
@clfhhc
Copy link
Author

clfhhc commented Nov 24, 2020

I have to reopen this issue because I still see it after upgrading the typescript to 4.1.2. The reproduction steps with my sample repo are still valid.

@Andarist
Copy link
Member

Please just apply this patch:

diff --git a/tsconfig.json b/tsconfig.json
index c8399a6..983beb9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,7 +21,8 @@
     "moduleResolution": "node",
     "resolveJsonModule": true,
     "isolatedModules": true,
-    "jsx": "preserve",
+    "jsx": "react-jsx",
+    "jsxImportSource": "@emotion/react",
     "baseUrl": "./src"
   },
   "include": [

This probably ain't mentioned anywhere in the docs - if you'd like to prepare one I would appreciate a PR for this.

@clfhhc
Copy link
Author

clfhhc commented Nov 24, 2020

Thanks. That works.
For NextJs build, it insists setting "jsx": "preserve":

> next build

We detected TypeScript in your project and reconfigured your tsconfig.json file for you.

The following mandatory changes were made to your tsconfig.json:

        - jsx was set to preserve (next.js implements its own optimized jsx transform)

@Andarist
Copy link
Member

Oh - I haven't realized that next enforces this. From what I looked up in their code they don't really use TS for transpiling at all so I'm not sure why do they insist on this value 🤷‍♂️

I have also thought that "jsx": "react-jsx" is required for "jsxImportSource" but it seems that it isn't - the latter works without the former when it comes to the JSX namespace lookup.

@clfhhc clfhhc closed this as completed Nov 24, 2020
wKovacs64 added a commit to wKovacs64/pwl that referenced this issue Dec 2, 2020
* chore(deps): update emotion monorepo to v11

* chore(deps): update emotion to v11

* chore(deps): temporarily add emotion css prop types globally

* chore(deps): explicitly include className prop on stylable components

...and specify jsxImportSource for TypeScript.

@see https://emotion.sh/docs/emotion-11#css-prop-types
@see emotion-js/emotion#2111 (comment)

* chore(deps): avoid the need for explicit className prop on AdditionalInfo children

Co-authored-by: Renovate Bot <[email protected]>
Co-authored-by: Justin Hall <[email protected]>
LukasKalbertodt added a commit to LukasKalbertodt/tobira that referenced this issue May 19, 2021
This required a change to the tsconfig. I found the current solution
here: emotion-js/emotion#2111 (comment)
LukasKalbertodt added a commit to LukasKalbertodt/tobira that referenced this issue May 20, 2021
This required a change to the tsconfig. I found the current solution
here: emotion-js/emotion#2111 (comment)
@justincorrigible
Copy link

justincorrigible commented Mar 30, 2022

Oh - I haven't realized that next enforces this.

For those coming here with the current vesions of NextJS and Emotion: Apart from enforcing tsconfig's "jsx": "preserve", they won't let you edit its next-env.d.ts either. I was able to get the css props back (as well as the theme typed correctly) using the triple slash suggested above (and in the docs) like so:

emotion.d.ts

/// <reference types="@emotion/react/types/css-prop" />

import '@emotion/react';
import { CustomThemeInterface } from '.';

declare module '@emotion/react' {
  export interface Theme extends CustomThemeInterface {}
}

@Andarist I may open a PR to update the docs with this, if you wish me to.

@Andarist
Copy link
Member

A PR documenting this would be very much appreciated. I wonder - are there any open issues in Next about this? Are there any arguments for maintaining the current behavior?

@justincorrigible
Copy link

justincorrigible commented Mar 30, 2022

A PR documenting this would be very much appreciated.

Happy to help! 🎉 PR coming right up.
Edit: #2703 @Andarist
Discarded in favour of possibly creating a new integration section in the docs instead.
Also linking the update PR in my repo, in case others may find my configs useful. 🤷

I wonder - are there any open issues in Next about this? Are there any arguments for maintaining the current behavior?

Based on what I've read looking through their "issues" on this subject (i.e. I'm speculating lol), they do their own JSX handling under the hood, so delegating it breaks their own runtime, performance optimisations, etc.

On the bright side, they seem to be porting the relevant babel plugins etc. to SCW (their own compiler), which may include the JSX runtime config option. 👍
vercel/next.js#30804


Update: Looking deeper into why my app didn't seem to be satisfied with just the babel plugin and jsxImportSource, I found my problem was caused by incorrect usage of the css props that may have been deprecated at some point.
The css does not exist on type... comes up if you don't have a className defined in your target component's props.
Documentation in this regard is not overly explicit for those of us less experienced with this library, and the error message itself may seem misleading (as it sure was to me lol).

That said, even though the solution I posted before may still be useful for some people, I can now confirm the /// reference doesn't seem necessary in NextJS + Typescript (as long as you're using the Babel plugins).

Ping @srmagura, re resolution to our earlier conversation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants