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

Custom _document file example for styled-components throws a TS bug after updating @types/react to ^18.0.0 #36008

Closed
1 task done
ppuzio opened this issue Apr 8, 2022 · 12 comments · Fixed by #36125
Closed
1 task done
Labels
bug Issue was opened via the bug report template. TypeScript Related to types with Next.js. Upstream Related to using Next.js with a third-party dependency. (e.g., React, UI/icon libraries, etc.).

Comments

@ppuzio
Copy link

ppuzio commented Apr 8, 2022

Verify canary release

  • I verified that the issue exists in Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 21.4.0: Fri Mar 18 00:47:26 PDT 2022; root:xnu-8020.101.4~15/RELEASE_ARM64_T8101
Binaries:
  Node: 17.4.0
  npm: 8.3.1
  Yarn: 1.22.17
  pnpm: N/A
Relevant packages:
  next: 12.1.4
  react: 18.0.0
  react-dom: 18.0.0

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Describe the Bug

I'm not entirely sure if it should be posted here or as an issue in the types/SC repo, so sorry if it shouldn't be here.
After updating @types/react to 18.0.0, I started noticing an error in the _documents.tsx file when using this approach for styled components.. I now get an error which says

Class static side 'typeof MyDocument' incorrectly extends base class static side 'typeof Document'.
  The types returned by 'getInitialProps(...)' are incompatible between these types.
    Type 'Promise<{ styles: Element; html: string; head?: (Element | null)[] | undefined; }>' is not assignable to type 'Promise<DocumentInitialProps>'.
      Type '{ styles: JSX.Element; html: string; head?: (JSX.Element | null)[] | undefined; }' is not assignable to type 'DocumentInitialProps'.
        Type '{ styles: JSX.Element; html: string; head?: (JSX.Element | null)[] | undefined; }' is not assignable to type '{ styles?: ReactFragment | ReactElement<any, string | JSXElementConstructor<any>>[] | undefined; }'.
          Types of property 'styles' are incompatible.
            Type 'Element' is not assignable to type 'ReactFragment | ReactElement<any, string | JSXElementConstructor<any>>[] | undefined'.
              Type 'ReactElement<any, any>' is missing the following properties from type 'ReactElement<any, string | JSXElementConstructor<any>>[]': length, pop, push, concat, and 29 more.ts(2417)

Upon further investigation I discovered that in this part:

      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };

the overwrite of styles seems to be causing trouble. styles are of type styles?: ReactFragment | ReactElement<any, string | JSXElementConstructor<any>>[] | undefined instead of JSX.Element. If we downgrade types back to "^17.0.43", it doesn't seem to be a problem anymore.

Expected Behavior

Types should work correctly if the example made by SC is still relevant.

To Reproduce

You can create a new project with create next-app --typescript and add the document from the file I linked above, you should see the error immediately.

@ppuzio ppuzio added the bug Issue was opened via the bug report template. label Apr 8, 2022
@yerffejytnac
Copy link

Chiming in because I am experiencing the same error after upgrading.

@waynelinks

This comment was marked as off-topic.

@balazsorban44 balazsorban44 added the TypeScript Related to types with Next.js. label Apr 9, 2022
@rafae2k
Copy link
Contributor

rafae2k commented Apr 9, 2022

You can fix it by returning an array as follows:

return {
        ...initialProps,
        styles: [
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>,
        ],
      };

I would be glad to contribute an example with types for the use of styled with next.js and Typescript.

Unfortunately, there are no official docs for that.

(Current example with no types)[https://github.com/vercel/next.js/blob/canary/examples/with-styled-components-babel/pages/_document.js]

@ppuzio
Copy link
Author

ppuzio commented Apr 11, 2022

One thing should be noted: if you're using

  compiler: {
    styledComponents: true,
  },

in next.config.js, then you don't need _document.tsx and this doesn't concern you ;) I think the info about this file being redundant was added recently.

@javlund
Copy link

javlund commented Apr 11, 2022

One thing should be noted: if you're using

  compiler: {
    styledComponents: true,
  },

in next.config.js, then you don't need _document.tsx and this doesn't concern you ;) I think the info about this file being redundant was added recently.

Unfortunately, this doesn't seem to be the case; not for me at least. I'm getting a FOUC even with

  compiler: {
    styledComponents: true,
  }

unless I have a _document.tsx with the boilerplate getInitialProps. Would love to get rid of it though.

@imaksp
Copy link
Contributor

imaksp commented Apr 11, 2022

You can fix it by returning an array as follows:

return {
        ...initialProps,
        styles: [
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>,
        ],
      };

I would be glad to contribute an example with types for the use of styled with next.js and Typescript.

Unfortunately, there are no official docs for that.

(Current example with no types)[https://github.com/vercel/next.js/blob/canary/examples/with-styled-components-babel/pages/_document.js]

This works but It introduced new warning:

Warning: Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.
at Head (webpack-internal:///./node_modules/next/dist/pages/_document.js:221:1)
at html
at Html (webpack-internal:///./node_modules/next/dist/pages/_document.js:186:73)
at MyDocument (webpack-internal:///./pages/_document.tsx:14:1)

@javlund
Copy link

javlund commented Apr 11, 2022

You can fix it by returning an array as follows:

return {
        ...initialProps,
        styles: [
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>,
        ],
      };

I would be glad to contribute an example with types for the use of styled with next.js and Typescript.
Unfortunately, there are no official docs for that.
(Current example with no types)[https://github.com/vercel/next.js/blob/canary/examples/with-styled-components-babel/pages/_document.js]

This works but It introduced new warning:

Warning: Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.
at Head (webpack-internal:///./node_modules/next/dist/pages/_document.js:221:1)
at html
at Html (webpack-internal:///./node_modules/next/dist/pages/_document.js:186:73)
at MyDocument (webpack-internal:///./pages/_document.tsx:14:1)

While I haven't tried it, I'm guessing that could be fixed with an explicit Fragment tag:

import {Fragment} from "react";
// ...
return {
        ...initialProps,
        styles: [
          <Fragment key="1">
            {initialProps.styles}
            {sheet.getStyleElement()}
          </Fragment>,
        ],
      };

@imaksp
Copy link
Contributor

imaksp commented Apr 11, 2022

@javlund Hi adding an explicit fragment tag & a key fixed that error but it introduced new TS error:

This JSX tag's 'children' prop expects a single child of type 'ReactNode', but multiple children were provided

Also getting another TS error in react date picker lib, so I am reverting to old react typings for now.

@balazsorban44
Copy link
Member

The reported issues here are coming from upstream/third-party libraries, and are not related to Next.js. These should be reported on the respective repositories.

Some useful links:

I'm closing this for now. If you still think there is a problem with Next.js itself, please provide a reproduction in a new issue so we can look more into it.

@balazsorban44 balazsorban44 added the Upstream Related to using Next.js with a third-party dependency. (e.g., React, UI/icon libraries, etc.). label Apr 12, 2022
@imaksp
Copy link
Contributor

imaksp commented Apr 13, 2022

@javlund your suggestion with <Fragment> works perfectly after running

npx yarn-deduplicate --packages @types/react
yarn

Actually React date picker lib has mentioned "@types/react": "*" in dependency so it might have caused the issue (found from React issue in above comment)

But with this I think Next.js official TS example with styled-components needs an update.

& it seems we need to add this even if we turn on styledComponents in compiler otherwise I am getting FOUC as mentioned by @ppuzio.

@tettoffensive
Copy link

I'm not really sure why the array is necessary as the type definition states:

export declare type DocumentInitialProps = RenderPageResult & {
    styles?: React.ReactElement[] | React.ReactFragment;
};

However, just trying to do a straight fragment without an array doesn't seem to work.

kodiakhq bot pushed a commit that referenced this issue Apr 27, 2022
This PR is looking forward to improve documentation exemples about usage of Next.js with Typescript and Styled-components. 

I added Typescript types to the original exemple [Example app with styled-components using babel
](https://github.com/vercel/next.js/tree/canary/examples/with-styled-components-babel)

## Feature

- [x] Related issues linked using 
- [x] Documentation added

## Documentation / Examples

- [x] Make sure the linting passes by running `yarn lint`

fixes #36008
@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. TypeScript Related to types with Next.js. Upstream Related to using Next.js with a third-party dependency. (e.g., React, UI/icon libraries, etc.).
Projects
None yet
8 participants