简体   繁体   English

React 类型文件在 React TypeScript (.tsx) 文件中不起作用 - 为 React 组件抛出 ESLint 错误

[英]React types files not working in React TypeScript (.tsx) file - Throwing ESLint errors for React Component

I have a React build configuration using Webpack, ESlint, Prettier and TypeScript.我有一个使用 Webpack、ESlint、Prettier 和 TypeScript 的 React 构建配置。

When I run the build it looks like I'm getting TypeScript linting errors that should be nullified by the @typings/react or @typings/react-dom packages.当我运行构建时,看起来我收到了应该被 @typings/react 或 @typings/react-dom 包取消的 TypeScript linting 错误。

Looking at the documentation I shouldn't need to define accessibility modifiers or return types for React Components: https://www.typescriptlang.org/docs/handbook/jsx.html查看文档,我不需要为 React 组件定义可访问性修饰符或返回类型: https : //www.typescriptlang.org/docs/handbook/jsx.html

This seems like the same issue as here: Missing return type on function - in react (typescript) code这似乎与此处的问题相同: Missing return type on function - in react (typescript) code

but installing the typings packages hasn't resolved the issue for me.但是安装打字包并没有解决我的问题。 Please note, I have also tried removing the @typings/react package as the @typings/react-dom has this as a dependency and this doesn't resolve the issue.请注意,我还尝试删除@typings/react包,因为@typings/react-dom将其作为依赖项,但这并不能解决问题。

Webpack config网络包配置

const webpack = require('webpack');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const path = require('path');

const createWebpackConfig = () => {
  const isProd =
    process.env &&
    process.env.NODE_ENV &&
    process.env.NODE_ENV === 'production';

  return {
    entry: ['@babel/polyfill', './index.tsx'],
    mode: isProd ? 'production' : 'development',
    module: {
      rules: [
        {
          enforce: 'pre',
          test: /(\.jsx|\.js|\.ts|\.tsx)$/,
          exclude: /node_modules/,
          loader: 'eslint-loader'
        },
        {
          test: /(\.jsx|\.js)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-react',
                [
                  '@babel/preset-env',
                  {
                    targets: 'cover 99.5% in GB'
                  }
                ]
              ],
              plugins: [
                '@babel/plugin-proposal-class-properties',
                '@babel/plugin-proposal-object-rest-spread'
              ],
              cacheDirectory: true
            }
          }
        },
        {
          test: /(\.tsx|\.ts)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-typescript',
                '@babel/preset-react',
                [
                  '@babel/preset-env',
                  {
                    targets: 'cover 99.5% in GB'
                  }
                ]
              ],
              plugins: [
                '@babel/plugin-proposal-class-properties',
                '@babel/plugin-proposal-object-rest-spread'
              ],
              cacheDirectory: true
            }
          }
        }
      ]
    },
    resolve: {
      modules: [path.resolve(__dirname, '/'), 'node_modules'],
      extensions: ['.ts', '.tsx', '.js', '.jsx'],
      enforceExtension: false
    },
    target: 'web',
    optimization: {
      splitChunks: {
        chunks: 'all',
        maxInitialRequests: Infinity,
        minSize: 0,
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendor'
          },
          main: {
            name: 'main'
          }
        }
      }
    },
    output: {
      path: path.join(__dirname, 'bundles'),
      filename: '[name].app.js',
      chunkFilename: '[name].bundle.js',
      pathinfo: true
    },
    plugins: [
      new CaseSensitivePathsPlugin(),
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(isProd ? 'production' : 'development')
        }
      })
    ]
  };
};

module.exports = createWebpackConfig;

ESLint config ESLint 配置

{
  "parser": "@typescript-eslint/parser", // Specifies the ESLint parser
  "extends": [
    "plugin:react/recommended",
    "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 displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
  ],
  "parserOptions": {
    "ecmaVersion": 10, // Allows for the parsing of modern ECMAScript features
    "sourceType": "module", // Allows for the use of imports
    "jsx": true
  },
  "rules": {
    "prettier/prettier": [
      "error",
      {
        "singleQuote": true,
        "endOfLine": "auto"
      }
    ]
  }
}

tsconfig.json配置文件

{
  "compilerOptions": {
    "module": "esnext",
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "jsx": "preserve"
  },
  "exclude": ["node_modules"]
}

package.json包.json

{
  "name": "reacttypescripttest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack --config ./webpack.config.js --progress --colors --watch --display-error-details"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.5.5",
    "@babel/plugin-proposal-class-properties": "^7.5.5",
    "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
    "@babel/polyfill": "^7.4.4",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-typescript": "^7.3.3",
    "@types/react": "^16.8.24",
    "@types/react-dom": "^16.8.5",
    "@typescript-eslint/eslint-plugin": "^1.13.0",
    "@typescript-eslint/parser": "^1.13.0",
    "babel-loader": "^8.0.6",
    "case-sensitive-paths-webpack-plugin": "^2.2.0",
    "cross-env": "^5.2.0",
    "eslint": "^6.1.0",
    "eslint-config-prettier": "^6.0.0",
    "eslint-loader": "^2.2.1",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-react": "^7.14.3",
    "mini-css-extract-plugin": "^0.8.0",
    "prettier": "^1.18.2",
    "prettier-eslint": "^9.0.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "typescript": "^3.5.3",
    "webpack-cli": "^3.3.6"
  },
  "devDependencies": {
    "webpack": "^4.39.1"
  }
}

File causing error (index.tsx)导致错误的文件 (index.tsx)

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
  render() {
    return <div>Running!</div>;
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

Errors错误

  5:3  error    Missing accessibility modifier on method definition render  @typescript-eslint/explicit-member-accessibility
  5:9  warning  Missing return type on function                             @typescript-eslint/explicit-function-return-type

The first error Missing accessibility modifier on method definition render is saying that you did not declare your render method as public or private or any other type ( more reading on types . When working with Typescript all class methods need to have be declared accordingly, depending if you want to have them accessible outside your class instance or not. For render method it should be public. Code below should work nicely for you:第一个错误Missing accessibility modifier on method definition render是说您没有将render方法声明为publicprivate或任何其他类型( 更多阅读类型。使用 Typescript 时,所有类方法都需要相应地声明,具体取决于你想让它们在你的类实例之外访问与否。对于render方法,它应该是公开的。下面的代码应该很适合你:

public render() {
   return <div>Running!</div>;
}

When it comes the 2nd error your're having, it means that your linter expects the render method to have declared what's the output of its' execution.当您遇到第二个错误时,这意味着您的 linter 期望render方法已声明其执行的输出是什么。 The correct type for render method is React.ReactNode , so your final code should look like below (assuming you're not importing ReactNode in the import statement earlier) render方法的正确类型是React.ReactNode ,因此您的最终代码应如下所示(假设您没有在之前的import语句中导入ReactNode

public render(): React.ReactNode {
   return <div>Running!</div>;
}

Edit 1编辑 1

Even if TS itself doesn't require all these annotations, the linter you're using does.即使 TS 本身不需要所有这些注释,您使用的 linter 也需要。 See their default rules - as you can see, the rules you're having trouble with are not turned off.查看他们的默认规则- 如您所见,您遇到问题的规则并未关闭。 The solution there would be disabling them in your app eslint config, like below:解决方案是在您的应用程序 eslint 配置中禁用它们,如下所示:

"rules": {
   "@typescript-eslint/explicit-function-return-type": "off",
   "@typescript-eslint/explicit-member-accessibility": "off"
}

If anyone is running into this AND using a tsx file already.如果有人遇到此问题并且已经使用 tsx 文件。 Makre sure that you've configured vscode to associate tsx files with TypescriptReact and not just Typescript. Makre 确保您已将 vscode 配置为将 tsx 文件与 TypescriptReact 相关联,而不仅仅是 Typescript。 When the tsx file is open, bottom right click on Typescript and set association.打开 tsx 文件后,右下角单击 Typescript 并设置关联。 vscode 状态栏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React typescript.tsx 文件扩展名 - React typescript .tsx files extensions 打字稿反应组件中的反应/道具类型eslint错误 - react/prop-types eslint error in typescript react component TypeScript 中基于配置的 React Router 抛出 eslint 错误 - Configuration based React Router in TypeScript throwing eslint errors 使用Typescript将道具传递给React中的子组件(TSX文件) - Pass props to child component in React, with Typescript (TSX file) 打字稿和@ types / react错误 - typescript and @types/react errors 在TypeScript(TSX)中需要一个React子组件 - Requiring a single React child component in TypeScript (TSX) 使用 mocha 测试 tsx 组件 - TypeScript、React 和 Mocha - Testing tsx component with mocha - TypeScript, React and Mocha tsx 文件中的条件(React + TypeScript) - Conditionals in tsx-files (React + TypeScript) 用 typescript 反应 CRA 不能与 eslint 一起使用 - React CRA with typescript not working with eslint 使用 tsx 组件名称循环对象列表(JSON 文件)并在 React tsx(TypeScript)中渲染它 渲染 JSON 中引用的 react-icons,如何? - Loop over List of Objects (JSON file) with tsx component name and render it in React tsx (TypeScript) Render react-icons referenced in JSON, how?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM