Hi!
I trying to setup a react/typescript/eslint/prettier project and noticed I can not override @typescript-eslint/no-unused-vars to show error, if extending react-app - it stills show warning.
Repro
.eslintrc:
{
"env": {
"browser": true,
"es6": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": ["@typescript-eslint", "react", "prettier"],
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"react-app", // !!! do not allow to override @typescript-eslint/no-unused-vars error
"plugin:prettier/recommended",
"prettier/@typescript-eslint"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/explicit-function-return-type": "off",
// note you must disable the base rule as it can report incorrect errors
"no-unused-vars": "off",
// !!! still "warn" if there is react-app in extends
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "after-used", "ignoreRestSiblings": true }],
// Seems to be incompatible with TS props type(?):
"react/prop-types": "off",
"prettier/prettier": "warn"
}
}
test.ts:
const unusedVar = 1;
run:
npx eslint ./test.ts
Expected Result
error 'unusedVar' is assigned a value but never used @typescript-eslint/no-unused-vars
Actual Result
warning 'unusedVar' is assigned a value but never used @typescript-eslint/no-unused-vars
Additional Info
npx eslint test.ts --debug
eslint:cli CLI args: [ 'test.ts', '--debug' ] +0ms
eslint:cli Running on files +4ms
eslint:glob-utils Creating list of files to process. +0ms
eslint:ignored-paths baseDir = "/home/www/test/front" +0ms
eslint:ignored-paths addPatternRelativeToCwd:
eslint:ignored-paths original = "/node_modules/*"
eslint:ignored-paths cooked = "/node_modules/*" +0ms
eslint:ignored-paths addPatternRelativeToCwd:
eslint:ignored-paths original = "/bower_components/*"
eslint:ignored-paths cooked = "/bower_components/*" +1ms
eslint:ignored-paths addPatternRelativeToCwd:
eslint:ignored-paths original = ".*"
eslint:ignored-paths cooked = ".*" +0ms
eslint:ignored-paths addPatternRelativeToCwd:
eslint:ignored-paths original = "!../"
eslint:ignored-paths cooked = "!../" +0ms
eslint:ignored-paths Looking for ignore file in /home/www/test/front +0ms
eslint:ignored-paths Could not find ignore file in cwd +0ms
eslint:ignored-paths contains: +1ms
eslint:ignored-paths target = "/home/www/test/front/test.ts" +0ms
eslint:ignored-paths result = false +0ms
eslint:ignored-paths contains: +0ms
eslint:ignored-paths target = "/home/www/test/front/test.ts" +0ms
eslint:ignored-paths result = false +0ms
eslint:cli-engine Processing /home/www/test/front/test.ts +0ms
eslint:cli-engine Linting /home/www/test/front/test.ts +0ms
eslint:config Constructing config file hierarchy for /home/www/test/front +0ms
eslint:config Using .eslintrc and package.json files +0ms
eslint:config Loading /home/www/test/front/.eslintrc +1ms
eslint:config-file Loading config file: /home/www/test/front/.eslintrc +0ms
eslint:plugins Loaded plugin @typescript-eslint (@typescript-eslint/[email protected]) (from /home/www/test/front/node_modules/@typescript-eslint/eslint-plugin/dist/index.js) +0ms
eslint:plugins Loaded plugin react ([email protected]) (from /home/www/test/front/node_modules/eslint-plugin-react/index.js) +62ms
eslint:plugins Loaded plugin prettier ([email protected]) (from /home/www/test/front/node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js) +2ms
eslint:config-file Loading prettier/@typescript-eslint +342ms
eslint:config-file Attempting to resolve eslint-config-prettier/@typescript-eslint +0ms
eslint:config-file Loading JS config file: /home/www/test/front/node_modules/eslint-config-prettier/@typescript-eslint.js +1ms
eslint:config-file Loading plugin:prettier/recommended +1ms
eslint:config-file Attempting to resolve eslint-plugin-prettier +0ms
eslint:config-file Loading JS config file: /home/www/test/front/node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js +0ms
eslint:config-file Loading prettier +0ms
eslint:config-file Attempting to resolve eslint-config-prettier +0ms
eslint:config-file Loading JS config file: /home/www/test/front/node_modules/eslint-config-prettier/index.js +1ms
eslint:config-file Loading react-app +0ms
eslint:config-file Attempting to resolve eslint-config-react-app +0ms
eslint:config-file Loading JS config file: /home/www/test/front/node_modules/eslint-config-react-app/index.js +1ms
eslint:plugins Loaded plugin import ([email protected]) (from /home/www/test/front/node_modules/eslint-plugin-import/lib/index.js) +80ms
eslint:plugins Loaded plugin flowtype ([email protected]) (from /home/www/test/front/node_modules/eslint-plugin-flowtype/dist/index.js) +15ms
eslint:plugins Loaded plugin jsx-a11y ([email protected]) (from /home/www/test/front/node_modules/eslint-plugin-jsx-a11y/lib/index.js) +82ms
eslint:plugins Loaded plugin react-hooks ([email protected]) (from /home/www/test/front/node_modules/eslint-plugin-react-hooks/index.js) +2ms
eslint:config-file Loading plugin:react/recommended +195ms
eslint:config-file Attempting to resolve eslint-plugin-react +0ms
eslint:config-file Loading JS config file: /home/www/test/front/node_modules/eslint-plugin-react/index.js +0ms
eslint:config-file Loading plugin:@typescript-eslint/recommended +8ms
eslint:config-file Attempting to resolve @typescript-eslint/eslint-plugin +0ms
eslint:config-file Loading JS config file: /home/www/test/front/node_modules/@typescript-eslint/eslint-plugin/dist/index.js +0ms
eslint:config-file Loading /home/www/test/front/node_modules/@typescript-eslint/eslint-plugin/dist/configs/base.json +24ms
eslint:config-file Loading JSON config file: /home/www/test/front/node_modules/@typescript-eslint/eslint-plugin/dist/configs/base.json +0ms
eslint:config Using /home/www/test/front/.eslintrc +574ms
eslint:config-ops Using config from partial cache +0ms
eslint:config-ops Apply environment settings to config +1ms
eslint:config-ops Creating config for environment browser +0ms
eslint:config-ops Creating config for environment commonjs +0ms
eslint:config-ops Creating config for environment es6 +0ms
eslint:config-ops Creating config for environment jest +0ms
eslint:config-ops Creating config for environment node +0ms
eslint:linter Linting code for /home/www/test/front/test.ts (pass 1) +0ms
eslint:linter Generating fixed text for /home/www/test/front/test.ts (pass 1) +327ms
eslint:source-code-fixer Applying fixes +0ms
eslint:source-code-fixer shouldFix parameter was false, not attempting fixes +0ms
eslint:cli-engine Linting complete in: 912ms +907ms
/home/www/test/front/test.ts
1:7 warning 'unusedVar' is assigned a value but never used @typescript-eslint/no-unused-vars
If remove react-app from extends - all ok!
eslint --printconfig diff (from without react-app to with react-app)
707a708,711
> "exports": true,
> "global": false,
> "module": false,
> "require": false,
764c768,789
< "WeakSet": false
---
> "WeakSet": false,
> "afterAll": false,
> "afterEach": false,
> "beforeAll": false,
> "beforeEach": false,
> "describe": false,
> "expect": false,
> "fdescribe": false,
> "fit": false,
> "it": false,
> "jest": false,
> "pit": false,
> "test": false,
> "xdescribe": false,
> "xit": false,
> "xtest": false,
> "__dirname": false,
> "__filename": false,
> "Buffer": false,
> "clearImmediate": false,
> "process": false,
> "setImmediate": false
768c793,796
< "es6": true
---
> "commonjs": true,
> "es6": true,
> "jest": true,
> "node": true
784c812
< "no-array-constructor": "off",
---
> "no-array-constructor": "warn",
795c823,829
< "no-unused-vars": "off",
---
> "no-unused-vars": [
> "off",
> {
> "args": "none",
> "ignoreRestSiblings": true
> }
> ],
804c838,845
< "no-use-before-define": "off",
---
> "no-use-before-define": [
> "warn",
> {
> "functions": false,
> "classes": false,
> "variables": false
> }
> ],
812,817c853,863
< "react/jsx-no-comment-textnodes": 2,
< "react/jsx-no-duplicate-props": 2,
< "react/jsx-no-target-blank": 2,
< "react/jsx-no-undef": 2,
< "react/jsx-uses-react": 2,
< "react/jsx-uses-vars": 2,
---
> "react/jsx-no-comment-textnodes": "warn",
> "react/jsx-no-duplicate-props": [
> "warn",
> {
> "ignoreCase": true
> }
> ],
> "react/jsx-no-target-blank": "warn",
> "react/jsx-no-undef": "error",
> "react/jsx-uses-react": "warn",
> "react/jsx-uses-vars": "warn",
819c865
< "react/no-danger-with-children": 2,
---
> "react/no-danger-with-children": "warn",
821c867
< "react/no-direct-mutation-state": 2,
---
> "react/no-direct-mutation-state": "warn",
823c869
< "react/no-is-mounted": 2,
---
> "react/no-is-mounted": "warn",
830,831c876,1152
< "react/react-in-jsx-scope": 2,
< "react/require-render-return": 2,
---
> "react/react-in-jsx-scope": "error",
> "react/require-render-return": "error",
> "array-callback-return": "warn",
> "default-case": [
> "warn",
> {
> "commentPattern": "^no default$"
> }
> ],
> "dot-location": [
> "off",
> "property"
> ],
> "eqeqeq": [
> "warn",
> "smart"
> ],
> "new-parens": "off",
> "no-caller": "warn",
> "no-cond-assign": [
> "warn",
> "except-parens"
> ],
> "no-const-assign": "warn",
> "no-control-regex": "warn",
> "no-delete-var": "warn",
> "no-dupe-args": "warn",
> "no-dupe-class-members": "warn",
> "no-dupe-keys": "warn",
> "no-duplicate-case": "warn",
> "no-empty-character-class": "warn",
> "no-empty-pattern": "warn",
> "no-eval": "warn",
> "no-ex-assign": "warn",
> "no-extend-native": "warn",
> "no-extra-bind": "warn",
> "no-extra-label": "warn",
> "no-fallthrough": "warn",
> "no-func-assign": "warn",
> "no-implied-eval": "warn",
> "no-invalid-regexp": "warn",
> "no-iterator": "warn",
> "no-label-var": "warn",
> "no-labels": [
> "warn",
> {
> "allowLoop": true,
> "allowSwitch": false
> }
> ],
> "no-lone-blocks": "warn",
> "no-loop-func": "warn",
> "no-mixed-operators": [
> 0,
> {
> "groups": [
> [
> "&",
> "|",
> "^",
> "~",
> "<<",
> ">>",
> ">>>"
> ],
> [
> "==",
> "!=",
> "===",
> "!==",
> ">",
> ">=",
> "<",
> "<="
> ],
> [
> "&&",
> "||"
> ],
> [
> "in",
> "instanceof"
> ]
> ],
> "allowSamePrecedence": false
> }
> ],
> "no-multi-str": "warn",
> "no-native-reassign": "warn",
> "no-negated-in-lhs": "warn",
> "no-new-func": "warn",
> "no-new-object": "warn",
> "no-new-symbol": "warn",
> "no-new-wrappers": "warn",
> "no-obj-calls": "warn",
> "no-octal": "warn",
> "no-octal-escape": "warn",
> "no-redeclare": "warn",
> "no-regex-spaces": "warn",
> "no-restricted-syntax": [
> "warn",
> "WithStatement"
> ],
> "no-script-url": "warn",
> "no-self-assign": "warn",
> "no-self-compare": "warn",
> "no-sequences": "warn",
> "no-shadow-restricted-names": "warn",
> "no-sparse-arrays": "warn",
> "no-template-curly-in-string": "warn",
> "no-this-before-super": "warn",
> "no-throw-literal": "warn",
> "no-undef": "error",
> "no-restricted-globals": [
> "error",
> "addEventListener",
> "blur",
> "close",
> "closed",
> "confirm",
> "defaultStatus",
> "defaultstatus",
> "event",
> "external",
> "find",
> "focus",
> "frameElement",
> "frames",
> "history",
> "innerHeight",
> "innerWidth",
> "length",
> "location",
> "locationbar",
> "menubar",
> "moveBy",
> "moveTo",
> "name",
> "onblur",
> "onerror",
> "onfocus",
> "onload",
> "onresize",
> "onunload",
> "open",
> "opener",
> "opera",
> "outerHeight",
> "outerWidth",
> "pageXOffset",
> "pageYOffset",
> "parent",
> "print",
> "removeEventListener",
> "resizeBy",
> "resizeTo",
> "screen",
> "screenLeft",
> "screenTop",
> "screenX",
> "screenY",
> "scroll",
> "scrollbars",
> "scrollBy",
> "scrollTo",
> "scrollX",
> "scrollY",
> "self",
> "status",
> "statusbar",
> "stop",
> "toolbar",
> "top"
> ],
> "no-unexpected-multiline": 0,
> "no-unreachable": "warn",
> "no-unused-expressions": [
> "error",
> {
> "allowShortCircuit": true,
> "allowTernary": true,
> "allowTaggedTemplates": true
> }
> ],
> "no-unused-labels": "warn",
> "no-useless-computed-key": "warn",
> "no-useless-concat": "warn",
> "no-useless-constructor": "warn",
> "no-useless-escape": "warn",
> "no-useless-rename": [
> "warn",
> {
> "ignoreDestructuring": false,
> "ignoreImport": false,
> "ignoreExport": false
> }
> ],
> "no-with": "warn",
> "no-whitespace-before-property": "off",
> "react-hooks/exhaustive-deps": "warn",
> "require-yield": "warn",
> "rest-spread-spacing": [
> "off",
> "never"
> ],
> "strict": [
> "warn",
> "never"
> ],
> "unicode-bom": [
> "off",
> "never"
> ],
> "use-isnan": "warn",
> "valid-typeof": "warn",
> "no-restricted-properties": [
> "error",
> {
> "object": "require",
> "property": "ensure",
> "message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
> },
> {
> "object": "System",
> "property": "import",
> "message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
> }
> ],
> "getter-return": "warn",
> "import/first": "error",
> "import/no-amd": "error",
> "import/no-webpack-loader-syntax": "error",
> "react/forbid-foreign-prop-types": [
> "warn",
> {
> "allowInPropTypes": true
> }
> ],
> "react/jsx-pascal-case": [
> "warn",
> {
> "allowAllCaps": true,
> "ignore": []
> }
> ],
> "react/no-typos": "error",
> "react/style-prop-object": "warn",
> "jsx-a11y/accessible-emoji": "warn",
> "jsx-a11y/alt-text": "warn",
> "jsx-a11y/anchor-has-content": "warn",
> "jsx-a11y/anchor-is-valid": [
> "warn",
> {
> "aspects": [
> "noHref",
> "invalidHref"
> ]
> }
> ],
> "jsx-a11y/aria-activedescendant-has-tabindex": "warn",
> "jsx-a11y/aria-props": "warn",
> "jsx-a11y/aria-proptypes": "warn",
> "jsx-a11y/aria-role": "warn",
> "jsx-a11y/aria-unsupported-elements": "warn",
> "jsx-a11y/heading-has-content": "warn",
> "jsx-a11y/iframe-has-title": "warn",
> "jsx-a11y/img-redundant-alt": "warn",
> "jsx-a11y/no-access-key": "warn",
> "jsx-a11y/no-distracting-elements": "warn",
> "jsx-a11y/no-redundant-roles": "warn",
> "jsx-a11y/role-has-required-aria-props": "warn",
> "jsx-a11y/role-supports-aria-props": "warn",
> "jsx-a11y/scope": "warn",
> "react-hooks/rules-of-hooks": "error",
> "flowtype/define-flow-type": "warn",
> "flowtype/require-valid-file-annotation": "warn",
> "flowtype/use-flow-type": "warn",
837d1157
< "no-mixed-operators": 0,
839d1158
< "no-unexpected-multiline": 0,
853d1171
< "dot-location": "off",
867d1184
< "new-parens": "off",
880d1196
< "no-whitespace-before-property": "off",
890d1205
< "rest-spread-spacing": "off",
909d1223
< "unicode-bom": "off",
919,920d1232
< "ecmaVersion": 2018,
< "sourceType": "module",
921a1234
> "globalReturn": true,
923c1236,1238
< }
---
> },
> "ecmaVersion": 2018,
> "sourceType": "module"
928a1244,1247
> "import",
> "flowtype",
> "jsx-a11y",
> "react-hooks",
935a1255
> "react-app",
938a1259
> "root": true,
Versions
| package | version |
| ---------------------------------- | ------- |
| @typescript-eslint/eslint-plugin | 1.10.2 |
| @typescript-eslint/parser | 1.10.2 |
| TypeScript | 3.4.5 |
| ESLint | 5.16.0 |
| node | 10.16.0 |
| npm | 6.9.0 |
as per the create react app config
https://github.com/facebook/create-react-app/blob/master/packages/eslint-config-react-app/index.js#L55-L58
it uses an override block, which forces the rule to be on as a warning for typescript.
you'll have to do the same if you want to change the rule to an error.
In fact, this is a bug in ESLint: https://github.com/eslint/eslint/issues/11510
This will be fixed in ESLint 6.0.0.
Awesome! I had no idea it was considered a bug!
Most helpful comment
In fact, this is a bug in ESLint: https://github.com/eslint/eslint/issues/11510
This will be fixed in ESLint 6.0.0.