reactjs - 修复使用 TypeScript 时由 Document<any> 和 ctx.renderPage = () 引发的 next.js _document.tsx 中的 ESLint 警告

标签 reactjs typescript eslint next.js

maxbause 很乐意为 Next.js 创建一个很好的样板项目,其中包括 GraphQL 和 TypeScript 中的样式组件。

https://github.com/maxbause/next-graphql-styled-components-ts-boilerplate/blob/master/pages/_document.tsx

尽管如此,当我将 ESLint 添加到项目中时,我收到了一些警告和错误,因为原因基本上是纯 JavaScript。

我修复了大部分问题,但在 _document.tsx 文件中遇到了两个警告。

首先,我在 Documentany 部分收到以下警告:“Unexpected any。请指定其他类型。” 如果我删除任何并且不使用任何内容,未知从不,那么我会收到this.props.styleTags错误.

第二个问题是 函数中缺少返回类型 警告,该警告是由 ctx.renderPage = () => 中的缺少返回类型引发的,紧随 尝试在我不知道应该添加什么的地方。

我对 TypeScript 有点菜鸟,所以如果有明显的解决方案,请不要对我太严厉。我搜索了很多但无法弄清楚。

我知道我可以忽略甚至禁用这些错误,但如果我要禁用这些错误,如果您能解释为什么这样做是有意义的,我将不胜感激。

我希望这个问题对每个有兴趣将 Next.js 与 TypeScript 一起使用的人都有用。

_document.tsx (抛出警告的地方)

import React from 'react';
import Document, { Head, Main, NextScript, DocumentContext, DocumentInitialProps } from 'next/document';
import { ServerStyleSheet } from 'styled-components';

export default class MyDocument extends Document<any> {
    static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
        const sheet = new ServerStyleSheet();
        const originalRenderPage = ctx.renderPage;

        try {
            // wraps the collectStyles provider around our <App />.
            ctx.renderPage = () =>
                originalRenderPage({
                    enhanceApp: App => (props): React.ReactElement => sheet.collectStyles(<App {...props} />),
                });

            // extract the initial props that may be present.
            const initialProps = await Document.getInitialProps(ctx);

            // returning the original props together with our styled components.
            return {
                ...initialProps,
                styles: (
                    <>
                        {initialProps.styles}
                        {sheet.getStyleElement()}
                    </>
                ),
            };
        } finally {
            sheet.seal();
        }
    }

    render(): JSX.Element {
        return (
            <html>
                <Head>{this.props.styleTags /*rendering the actually stylesheet*/}</Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </html>
        );
    }
}

.eslintrc.js

var OFF = 0, WARN = 1, ERROR = 2;

module.exports = {
    parser: '@typescript-eslint/parser', // Specifies the ESLint parser
    extends: [
        'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
        'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
        'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
        'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
    ],
    parserOptions: {
        ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
        sourceType: 'module', // Allows for the use of imports
        ecmaFeatures: {
            jsx: true, // Allows for the parsing of JSX
        },
    },
    rules: {
        '@typescript-eslint/interface-name-prefix': [ERROR, {'prefixWithI': 'always'}]
        // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
        // e.g. "@typescript-eslint/explicit-function-return-type": "off",
    },
    settings: {
        react: {
            version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
        },
    },
};

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "exclude": [
    "node_modules"
  ],
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ]
}

package.json

{
    "name": "killer-frontend",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "dependencies": {
        "@apollo/react-hooks": "^3.1.3",
        "apollo-boost": "^0.4.7",
        "graphql": "^14.5.8",
        "next": "^9.1.6",
        "next-with-apollo": "^4.3.0",
        "node-fetch": "^2.6.0",
        "react": "^16.12.0",
        "react-dom": "^16.12.0",
        "styled-components": "^5.0.1"
    },
    "scripts": {
        "dev": "next",
        "build": "next build",
        "start": "next start",
        "lint": "tsc --noEmit && eslint '*/**/*.{js,ts,tsx}' --quiet --fix"
    },
    "devDependencies": {
        "@types/node": "^13.1.1",
        "@types/react": "^16.9.17",
        "@types/styled-components": "^5.0.1",
        "@typescript-eslint/eslint-plugin": "^2.23.0",
        "@typescript-eslint/parser": "^2.23.0",
        "babel-plugin-styled-components": "^1.10.7",
        "eslint": "^6.8.0",
        "eslint-config-prettier": "^6.10.0",
        "eslint-plugin-prettier": "^3.1.2",
        "eslint-plugin-react": "^7.19.0",
        "prettier": "^1.19.1",
        "typescript": "^3.7.4"
    }
}

最佳答案

static getInitialProps({ renderPage }: DocumentContext): Promise<RenderPageResult> {
   return Promise.resolve<RenderPageResult>(renderPage())
}

为我工作

UPD,带有样式组件

static async getInitialProps(ctx: DocumentContext): Promise<RenderPageResult> {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    const initialProps = await Document.getInitialProps(ctx);

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
        });

      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      } as RenderPageResult;
    } catch {
      return initialProps;
    } finally {
      sheet.seal();
    }
  }

关于reactjs - 修复使用 TypeScript 时由 Document<any> 和 ctx.renderPage = () 引发的 next.js _document.tsx 中的 ESLint 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60697385/

相关文章:

reactjs - 如何将 createEntityAdapter 应用于 createApi 切片

javascript - 如何显示成功消息 NgRX Effects 和调度事件

javascript - Eslint "No files matching the pattern "lint“被发现。请检查模式中的输入错误。”错误

javascript - 使用 React 开发时窗口焦点的变化

javascript - 用于首选 React 类组件语法的 eslint 规则

reactjs - create-react-app —如何将EXTEND_ESLINT设置为true?

android - React Native 是否带有 Gradle?

typescript - 尝试使用 Karma 为 Typescript 项目设置单元测试

angular - 在 IONIC 3 中,如何在 ios 上上传 word 或 pdf 等文件?

javascript - React js问题