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

no-unused-expressions warning for optional chaining #8107

Open
iansan5653 opened this issue Dec 6, 2019 · 33 comments
Open

no-unused-expressions warning for optional chaining #8107

iansan5653 opened this issue Dec 6, 2019 · 33 comments

Comments

@iansan5653
Copy link

Describe the bug

I just upgrade react-scripts to 3.3.0. I am able to use nullish coalescing, but when I attempt to use optional chaining, I can't compile as I get this error:

./src/components/Select/Select.tsx
  Line 141:5:  Expected an assignment or function call and instead saw an expression  no-unused-expressions

Search for the keywords to learn more about each error.

The line in question is:

    this.props.onChange?.(resultingValue);

Did you try recovering your dependencies?

No, I don't have time at the moment. If this might help I'll try it.

Which terms did you search for in User Guide?

I searched for optional chaining, no-unused-expressions, eslint optional chaining.

Environment

npx: installed 91 in 30.467s

Environment Info:

  System:
    OS: Windows 10 10.0.17134
    CPU: (8) x64 Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
  Binaries:
    Node: 12.2.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 6.9.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: 42.17134.1098.0
    Internet Explorer: 11.0.17134.1
  npmPackages:
    react: ^16.12.0 => 16.12.0
    react-dom: ^16.12.0 => 16.12.0
    react-scripts: 3.3.0 => 3.3.0
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

  1. Use optional chaining.
  2. Attempt to run npm start.

Expected behavior

I expected the app to compile and for the code to function like:

    this.props.onChange !== undefined && this.props.onChange(resultingValue);

Actual behavior

The app failed to compile and gave the above message.

@heyimalex
Copy link
Contributor

heyimalex commented Dec 6, 2019

It looks like those features just aren't currently supported by eslint? From #8003 it looks like we support using them with typescript, but until eslint lands support I'm not sure there's a solution. Take this with a grain of salt because I wasn't involved in landing those features.

@iansan5653
Copy link
Author

I knew it looked like an eslint error, but why are eslint errors preventing the page from rendering? I believe in linting but I'm not sure I can see a good reason for preventing compiling if there's a lint problem.

Until they add support, how can we disable this rule for CRA?

Your link is broken btw, correct link: eslint/eslint#12642

@heyimalex
Copy link
Contributor

I think that you can't on a project level; we only support overriding with inline comments. You might be better off just not using optional chaining (unless you're using typescript) until a fix for this lands in eslint. I'm sorry, I know that isn't a great answer.

@iansan5653
Copy link
Author

Sorry, I should've mentioned this previously - I am using TypeScript. How can I make it work in that case?

@heyimalex
Copy link
Contributor

You can only use it in typescript files. Using a fresh install with --template typescript and adding this to App.tsx doesn't emit an error for me.

const foo = {} as any;
foo.unknown?.();

Just to be clear, I can reproduce in js files.

@ianschmitz ianschmitz added this to the 3.3.1 milestone Dec 9, 2019
@danielkcz
Copy link

danielkcz commented Dec 13, 2019

Support already exists, you need to enable @typescript-eslint/no-unused-expressions instead of no-unused-expressions.

typescript-eslint/typescript-eslint#1241 (comment)

I tried when I enable typescript variant but keep regular one and sadly, it will complain. Only when that regular rule is explicitly disabled, it works correctly.

image

So shouldn't that rule be enabled in eslint-config-react-app instead? It should work for JS files just fine if I am not mistaken.

Oh I see it's been already done: #8003

@josias-r
Copy link

Just wanted to add, that you need TS < 3.7 for this to work, if that wasn't clear yet.
Optional chaining is working fine with my project.

@danielkcz
Copy link

@josias-r What? :) Optional chaining is a feature of TS 3.7. Whatever is working for you, might be because you have Babel somewhere in there 🤷‍♂

@josias-r
Copy link

josias-r commented Dec 22, 2019

@FredyC sorry meant to say TS 3.7 or higher. I have no special babel setup in my project. react-scripts 3.3.0 and prettier is installed and I can use optional chaining without problems in TSX files.

@danielkcz
Copy link

I think this issue can be closed now because eslint-config-react-app@5.1.0 is correctly using @typescript-eslint/no-unused-expressions for ts/tsx files.

@heyimalex
Copy link
Contributor

I’m going to treat this as the tracking issue for optional chaining in non-typescript files, since that still isn’t supported afaik.

@heyimalex
Copy link
Contributor

It looks like there's a workaround by using eslint-plugin-babel if anyone wants to try that out?

@mofojed
Copy link

mofojed commented Apr 17, 2020

I tried using eslint-plugin-babel but I was still getting the no-unused-expression error when running npm start (even with 'no-unused-expressions': 'off', set in .eslintrc)

@RiZKiT
Copy link

RiZKiT commented Apr 27, 2020

How about this solution: babel/eslint-plugin-babel#185 (comment)?

@mofojed
Copy link

mofojed commented Apr 27, 2020

@RiZKiT Yes I tried that solution, and I'm still seeing the error when running npm start.
I installed eslint-plugin-babel, added babel to the plugins section and the following to the rules section in .eslintrc:

    'no-unused-expressions': 'off',
    'babel/no-unused-expressions': 'error',

I still get the error when running npm start in my jsx file:

./src/console/notebook/Editor.jsx
  Line 44:5:  Expected an assignment or function call and instead saw an expression  no-unused-expressions

The line in question:

this.editor?.trigger('toggleFind', 'actions.find');

@TheDSCPL
Copy link

TheDSCPL commented Jun 4, 2020

For Typescript, FredyC's answer is the solution. Thanks!
Nevertheless, there should be a way for the no-unused-expressions rule to work on vanilla JS because it is valid syntax when using the Babel plugin and in ECMAScript 2020.

@taylankasap
Copy link

@mofojed You're also supposed to use "parser": "babel-eslint" (I think)

@Sleepful
Copy link

Sleepful commented Jul 3, 2020

@mofojed weird! it worked for me with:

    "no-unused-expressions": 0,
    "babel/no-unused-expressions": 1

do not forget to add to your eslintrc:

{
  "plugins": [
    "babel"
  ]
}

as the readme says

@trdaya
Copy link

trdaya commented Jul 31, 2020

@mofojed weird! it worked for me with:

    "no-unused-expressions": 0,
    "babel/no-unused-expressions": 1

do not forget to add to your eslintrc:

{
  "plugins": [
    "babel"
  ]
}

as the readme says

Sadly, not working for me

@bradydowling
Copy link

bradydowling commented Aug 21, 2020

Seems like this should be working now for Typescript according to this issue (eslint/eslint#12822) but it's still not working for me so I probably need to update one of my dependencies, just don't want to go through the list right now.

Update: Just double checked that I have @typescript-eslint/parser 3.10.1 installed, which was released just a week ago so it should have the fix in it. Not sure what other packages I might need to update.

Update 2: After looking at the answer from @FredyC, I added the following to my eslint config and now I'm all set:

  "overrides": [
    {
      "files": ["**/*.tsx", "**/*.ts"],
      "rules": {
        "no-unused-expressions": "off",
      }
    }
  ],

@KathyDinhTW
Copy link

after upgrading typescript-eslint to latest version (v4.1.0) today, my app build also starts to fail with Expected an assignment or function call and instead saw an expression @typescript-eslint/no-unused-expressions for a line with optional chaining function call.
Overriding eslint config to turn off the rule did not work for me. Had to temporarily revert back to the old-fashioned conditional function call

"@typescript-eslint/eslint-plugin": "^4.1.0", "@typescript-eslint/parser": "^4.1.0",

@koriner
Copy link

koriner commented Sep 10, 2020

Since updating to TS 4 & @typescript-eslint/* 4.1 this linting error seems to be impossible to stop when using optional chaining.

Expected an assignment or function call and instead saw an expression @typescript-eslint/no-unused-expressions is thrown regardless of whether we turn off the actual rule or not.

@xumix
Copy link

xumix commented Sep 16, 2020

Same here, no matter what I do, @typescript-eslint/no-unused-expressions keeps popping up

@peteschmitz
Copy link

peteschmitz commented Sep 20, 2020

Also encountering an issue where optional-chaining typescript is throwing false-positives at build-time. Introduced after updating react-scripts (3.4.3), eslint, and typescript packages.

Settings via my .eslintrc file seem to run perfectly fine with eslint CLI. However, when I run react-scripts build I encounter the error @koriner mentioned at the first sight of an optional-chain.

I attempted to disable @typescript-eslint/no-unused-expressions and no-unused-expressions rules via the eslintConfig section in my package.json with no avail.

@cglacet
Copy link

cglacet commented Sep 22, 2020

@Sleepful It seems like it doesn't work for me, my .eslintrc:

{
    "parser": "babel-eslint",
    "plugins": [
        "babel"
    ],
    "extends": [
        "react-app",
    ],
    "rules": {
        "no-unused-expressions": "off",
        "babel/no-unused-expressions": "error"
    }
}

I get this error:

Expected an assignment or function call and instead saw an expression.eslint(babel/no-unused-expressions)

EDIT for some strange reason, if I remove everything from my .eslintrc, it just works, not sure what's causing the issue but I'll investigate.

Maybe "extends": ["react-app"] turn no-unused-expressions off. If I only remove my rules and this extends it works too.

@TurboLion
Copy link

if I remove everything from my .eslintrc, it just works, not sure what's causing the issue but I'll investigate.

Running into the same issue, but clearing .eslintrc didn't help.

@cglacet any luck with the investigation?

@cglacet
Copy link

cglacet commented Oct 16, 2020

@TurboLion no, sorry.

@xumix
Copy link

xumix commented Oct 16, 2020

I've managed to mitigate the problem this way:

.eslintrc.json

"extends": ["react-app", "eslint:recommended"],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "tsconfig.json",
    "sourceType": "module"
  },
"plugins": ["react", "@typescript-eslint", "@typescript-eslint/eslint-plugin", "prefer-arrow"],
"rules": {
    "no-unused-expressions": "off",
    "@typescript-eslint/no-unused-expressions": "error"
}

package.json

"typescript": "^4.0.3",
    "@typescript-eslint/eslint-plugin": "^4.4.1",
    "@typescript-eslint/parser": "^4.4.1",
    "@typescript-eslint/typescript-estree": "^4.4.1",

remove node_modules and run npm install

@scottdevito
Copy link

I've managed to mitigate the problem this way:

.eslintrc.json

"extends": ["react-app", "eslint:recommended"],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "tsconfig.json",
    "sourceType": "module"
  },
"plugins": ["react", "@typescript-eslint", "@typescript-eslint/eslint-plugin", "prefer-arrow"],
"rules": {
    "no-unused-expressions": "off",
    "@typescript-eslint/no-unused-expressions": "error"
}

package.json

"typescript": "^4.0.3",
    "@typescript-eslint/eslint-plugin": "^4.4.1",
    "@typescript-eslint/parser": "^4.4.1",
    "@typescript-eslint/typescript-estree": "^4.4.1",

remove node_modules and run npm install

Tried this too (+ every other suggestion in this thread) but still can't get past the same no-unused-expressions error.

@Paul6552
Copy link

@scottdevito
The solution for me was updating "react-scripts" to version 4. Maybe this can help, because i have the same eslintrc.json and package.json as you

@k-funk
Copy link

k-funk commented Oct 29, 2020

TLDR: npm run eject

Other than upgrading to 4.x, I think that most people's issues are because they are installing eslint plugins themselves, which is a good thing if you want to start improving code quality in your repo! But once you do that, you'll probably find yourself in the abyss since CRA doesn't let you turn off their implementation of eslint.

Part of the reason why you might be struggling to find out why your rule-overrides aren't working, is because CRA...wait for it... will cache your lint config! (noted in #9154 and #9007), making it even harder to debug where the issue lies with the convoluted mess of "who's really in control, and what version of each plugin is actually being used?".

While debugging, make sure you purge that cache in between runs:

rm -rf node_modules/.cache/eslint-loader && npm run build

Also note the undocumented (maybe it was at some point, but their docs aren't versioned so 🤷‍♂️ ) env var EXTEND_ESLINT=true that you must set in order for your custom rules to be read. Fortunately, that env var seems to be going away in 4.x.


My solution actually involves doing something you shouldn't do, and it'll probably bite me in the butt:

Setting EXTEND_ESLINT=true only in my .env.development, so that in prod it's not trying to run my new rules. Then the ugly part, which you should generally never do:

# package.json

  "dependencies": {
    "@typescript-eslint/eslint-plugin": "^2.34.0",
    "@typescript-eslint/parser": "^2.34.0",
    "react-scripts": "3.4.3",
    ...
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^4.5.0",
    "@typescript-eslint/parser": "^4.5.0",
    ...
  }

And then changing my production build from using npm ci to npm i to accommodate for my hack.

If I only list my upgrades devDependencies, my prod build (NODE_ENV=production npm ci && npm run build) will complain that unmet peerDependencies (@typescript-eslint/eslint-plugin) aren't met, and the linter will blow up during npm run build.

You might not run into this issue if you aren't checking in your package-lock.json and not using npm run ci during a prod build, but you probably should be.


All of this headache could be avoided if there was just an option to let people turn off the linter, at least during a production build.

Next on my plate: convincing my team that we will be okay if we eject.

@jsdf
Copy link

jsdf commented Dec 6, 2020

this issue seems to be fixed in react-scripts@4.0.0

@Unsleeping
Copy link

this issue seems to be fixed in react-scripts@4.0.0

it works for me, thank u

@raix raix modified the milestones: 5.1, 5.x Dec 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests