diff --git a/docusaurus/docs/adding-typescript.md b/docusaurus/docs/adding-typescript.md index 40c9c2242a8..057372dce05 100644 --- a/docusaurus/docs/adding-typescript.md +++ b/docusaurus/docs/adding-typescript.md @@ -26,11 +26,11 @@ yarn create react-app my-app --template typescript To add [TypeScript](https://www.typescriptlang.org/) to a Create React App project, first install it: ```sh -npm install --save typescript @types/node @types/react @types/react-dom @types/jest +npm install --save typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser @types/node @types/react @types/react-dom @types/jest # or -yarn add typescript @types/node @types/react @types/react-dom @types/jest +yarn add typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser @types/node @types/react @types/react-dom @types/jest ``` Next, rename any file to be a TypeScript file (e.g. `src/index.js` to `src/index.tsx`) and **restart your development server**! diff --git a/packages/cra-template-typescript/template.json b/packages/cra-template-typescript/template.json index c50d194cb06..5da99d184d9 100644 --- a/packages/cra-template-typescript/template.json +++ b/packages/cra-template-typescript/template.json @@ -8,7 +8,9 @@ "@types/react": "^16.9.0", "@types/react-dom": "^16.9.0", "@types/jest": "^24.0.0", - "typescript": "^3.8.0" + "typescript": "^3.8.0", + "@typescript-eslint/eslint-plugin": "^2.28.0", + "@typescript-eslint/parser": "^2.28.0" } } } diff --git a/packages/eslint-config-react-app/README.md b/packages/eslint-config-react-app/README.md index d71c8d31489..011aeb82e6e 100644 --- a/packages/eslint-config-react-app/README.md +++ b/packages/eslint-config-react-app/README.md @@ -19,7 +19,7 @@ If you want to use this ESLint configuration in a project not built with Create First, install this package, ESLint and the necessary plugins. ```sh -npm install --save-dev eslint-config-react-app @typescript-eslint/eslint-plugin@2.x @typescript-eslint/parser@2.x babel-eslint@10.x eslint@6.x eslint-plugin-flowtype@4.x eslint-plugin-import@2.x eslint-plugin-jsx-a11y@6.x eslint-plugin-react@7.x eslint-plugin-react-hooks@2.x +npm install --save-dev eslint-config-react-app babel-eslint@10.x eslint@6.x eslint-plugin-flowtype@4.x eslint-plugin-import@2.x eslint-plugin-jsx-a11y@6.x eslint-plugin-react@7.x eslint-plugin-react-hooks@2.x ``` Then create a file named `.eslintrc.json` with following contents in the root folder of your project: diff --git a/packages/eslint-config-react-app/index.js b/packages/eslint-config-react-app/index.js index 0d29e7995a6..37497420251 100644 --- a/packages/eslint-config-react-app/index.js +++ b/packages/eslint-config-react-app/index.js @@ -23,37 +23,18 @@ // To use them, explicitly reference them, e.g. `window.name` or `window.status`. const restrictedGlobals = require('confusing-browser-globals'); -module.exports = { - root: true, - - parser: 'babel-eslint', - - plugins: ['import', 'flowtype', 'jsx-a11y', 'react', 'react-hooks'], - - env: { - browser: true, - commonjs: true, - es6: true, - jest: true, - node: true, - }, +const resolve = require('resolve'); +const path = require('path'); +const fs = require('fs'); - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, +const overrides = []; - settings: { - react: { - version: 'detect', - }, - }, - - overrides: [ - { +// Lint tsx only if typescript is installed. +try { + resolve.sync('typescript', { + basedir: path.resolve(fs.realpathSync(process.cwd()), 'node_modules') + }); + overrides.push({ files: ['**/*.ts?(x)'], parser: '@typescript-eslint/parser', parserOptions: { @@ -111,8 +92,43 @@ module.exports = { 'no-useless-constructor': 'off', '@typescript-eslint/no-useless-constructor': 'warn', }, + }) +} catch(e) { + if (e.code !== 'MODULE_NOT_FOUND') { + throw e; + } +} + +module.exports = { + root: true, + + parser: 'babel-eslint', + + plugins: ['import', 'flowtype', 'jsx-a11y', 'react', 'react-hooks'], + + env: { + browser: true, + commonjs: true, + es6: true, + jest: true, + node: true, + }, + + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + + settings: { + react: { + version: 'detect', }, - ], + }, + + overrides, // NOTE: When adding rules here, you need to make sure they are compatible with // `typescript-eslint`, as some rules such as `no-array-constructor` aren't compatible. diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json index 14c11fa0f6f..e106f10f1f8 100644 --- a/packages/eslint-config-react-app/package.json +++ b/packages/eslint-config-react-app/package.json @@ -25,7 +25,16 @@ "eslint-plugin-react": "7.x", "eslint-plugin-react-hooks": "1.x || 2.x" }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "@typescript-eslint/parser": { + "optional": true + } + }, "dependencies": { - "confusing-browser-globals": "^1.0.9" + "confusing-browser-globals": "^1.0.9", + "resolve": "^1.16.0" } } diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index a5983f373c2..146970749c8 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -31,8 +31,6 @@ "@babel/core": "7.9.0", "@pmmmwh/react-refresh-webpack-plugin": "0.3.0-beta.1", "@svgr/webpack": "4.3.3", - "@typescript-eslint/eslint-plugin": "^2.10.0", - "@typescript-eslint/parser": "^2.10.0", "babel-eslint": "10.1.0", "babel-jest": "^24.9.0", "babel-loader": "8.1.0", @@ -91,11 +89,19 @@ "fsevents": "2.1.2" }, "peerDependencies": { - "typescript": "^3.2.1" + "typescript": "^3.2.1", + "@typescript-eslint/eslint-plugin": "^2.28.0", + "@typescript-eslint/parser": "^2.28.0" }, "peerDependenciesMeta": { "typescript": { "optional": true + }, + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "@typescript-eslint/parser": { + "optional": true } }, "browserslist": {