Skip to content

Bug: [no-misused-promises] Possible false positive in 5.27.0 #5121

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

Closed
4 tasks done
doberkofler opened this issue May 31, 2022 · 14 comments
Closed
4 tasks done

Bug: [no-misused-promises] Possible false positive in 5.27.0 #5121

doberkofler opened this issue May 31, 2022 · 14 comments
Labels
fix: user error issue was fixed by correcting the configuration / correcting the code package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin working as intended Issues that are closed as they are working as intended

Comments

@doberkofler
Copy link
Contributor

doberkofler commented May 31, 2022

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ and my problem is not listed.

Playground Link

https://typescript-eslint.io/play/#ts=4.7.2&sourceType=module&code=C4TwDgpgBAJghsOAVc0C8UDeBXAzhAJwEsYAuKAO2wFsAjQgXwG4AoFgM2woGNgiB7CrARwA4hGAA1OABsSCCAAowcAnAD85AEoRu-AjAA8uYMQoBzADRQuAawr8A7hQB8UAD6VsMmQEpyAAoE-NRE+IZ2Ds5umCxQUAQS2ARCQSFhEAB0ibj8MgBuSipqvqwMbBAAHmD6wFBwuCA8UJw8fIJQ+DKKeIQk5FR0hP5QaaHh8IgokB5ePjFxUHoUJsKIUBhwjnBEdZNiEtJyk0o4+MQwDL71uKPB4xCG+9PQnlTzrPFE7FCK+1AAQjQGHefiwi3iiWAySEsXi8KgmSR+0sEKgzEW5UWUJhcxkZRYQA&eslintrc=N4KAkARApgHgLlAdgEwM4QFwAIDa5IAOANgK4DmAlohgAJwCeBUqAxgE4UFwC0zRVcAPR8B3NlBYB7ALbSkyKMggAafBGLkqtBk1YcuvVP0RCAhkSIQQWLAF1VNiGxJFmmLKBuO6jZu048IiaCiJLc0hSoJKiK3ARsMpFu2HheXtBsCWwq1mkeuXlYECwAFhIA1qgAapIUyABKUHAkbIjuAGbmMQVeAL49ttb9vUA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA

Repro Code

export async function sel(key: pkType): Promise<showProfileType | null> {
	const data = await dataGetValidate('!LAS_MOD_User_JSON.getEmpl', {emplid: key.emplid}) as Promise<showProfileType | null>;
	if (data !== null) {
		return {
			...data, // eslint-disable-line @typescript-eslint/no-misused-promises
			removeimg: false,
			removesign: false,
		};
	}

	return null;
}

ESLint Config

{
  "parser": "/Users/doberkofler/MyDev/ljs_app/trunk/periscope/node_modules/@typescript-eslint/parser/dist/index.js",
  "parserOptions": {
    "project": [
      "./tsconfig.json",
      "./test/selenium/tsconfig.json"
    ]
  },
  "plugins": [
    "@typescript-eslint"
  ],
  "rules": {
    "@typescript-eslint/no-misused-promises": "error"
  }
}

tsconfig

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false,
    "skipLibCheck": true,
    "noEmit": true,
    "downlevelIteration": true,
    "sourceMap": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": false,
    "noUnusedLocals": true,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": false,
    "useUnknownInCatchVariables": true,
    "exactOptionalPropertyTypes": false,
    "esModuleInterop": true,
    "declaration": false,
    "importHelpers": true,
    "moduleResolution": "node",
    "target": "es2017",
    "module": "esnext",
    "jsx": "react",
    "baseUrl": "../",
    "outDir": "../temp",
    "removeComments": true,
    "lib": [
      "dom"
    ],
    "paths": {
      "@alias_root/*": [
        "./*"
      ]
    }
  },
  "compileOnSave": false,
  "include": [
    "src/**/*",
    "test/unittest/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}

Expected Result

I would not expect the warning (this still worked in version 5.26.0)

Actual Result

The warning Expected a non-Promise value to be spreaded in an object @typescript-eslint/no-misused-promises in shown since the upgrade to version 5.27.0

Additional Info

Unfortunately, I was not able to reproduce the error in the playground

Versions

package version
@typescript-eslint/eslint-plugin 5.27.0
@typescript-eslint/parser 5.27.0
TypeScript 4.7.2
ESLint 8.16.0
node 18.1.0
@doberkofler doberkofler added bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for team members to take a look labels May 31, 2022
@armano2
Copy link
Collaborator

armano2 commented May 31, 2022

this is working correctly -> it should warn you about this,


currently you are casting awaited value to Promise

const data = await dataGetValidate({userid}) as Promise<dataType | null>;

this code is interpreted as

const data = (await dataGetValidate({userid})) as Promise<dataType | null>;

image


Solution:

-  const data = await dataGetValidate({userid}) as Promise<dataType | null>;
+  const data = await (dataGetValidate({userid}) as Promise<dataType | null>);

i copied your tsconfig to be able to reproduce this see repro

@bradzacher

This comment was marked as off-topic.

@bradzacher
Copy link
Member

@armano is correct!
await has a lower precedence than as - meaning instead of

await (thing as Promise)

you have

(await thing) as promise

The rule is working correctly and has caught a bug in your code!

@bradzacher bradzacher added working as intended Issues that are closed as they are working as intended fix: user error issue was fixed by correcting the configuration / correcting the code and removed bug Something isn't working triage Waiting for team members to take a look labels May 31, 2022
@doberkofler
Copy link
Contributor Author

doberkofler commented May 31, 2022

this is working correctly -> it should warn you about this,

currently you are casting awaited value to Promise

const data = await dataGetValidate({userid}) as Promise<dataType | null>;

this code is interpreted as

const data = (await dataGetValidate({userid})) as Promise<dataType | null>;

image

Solution:

-  const data = await dataGetValidate({userid}) as Promise<dataType | null>;
+  const data = await (dataGetValidate({userid}) as Promise<dataType | null>);

i copied your tsconfig to be able to reproduce this see repro

@armano2 Thank you for you feedback. I understand and was actually thinking the same but when using const data = (await dataGetValidate({userid})) as Promise<dataType | null>; the rule '@typescript-eslint/no-misused-promises': ['error', {checksVoidReturn: false}] complains about Unnecessary parentheses around expression.

@doberkofler

This comment was marked as off-topic.

@doberkofler
Copy link
Contributor Author

i copied your tsconfig to be able to reproduce this see repro

@armano2 Would be be so kind and tell me what I did miss in the Playground? I tried for quite some time and somehow was not able to reproduce the problem.

@armano2
Copy link
Collaborator

armano2 commented May 31, 2022

you forgot to input your tsconfig, and to be precise "target": "es2017"

image


recently we did some changes how you have to input configs, to give users easier way to reproduce issues

@doberkofler
Copy link
Contributor Author

you forgot to input your tsconfig, and to be precise "target": "es2017"

image

@armano2 Thank you. I must somehow have removed the target and then missed to put it back.

@bradzacher
Copy link
Member

bradzacher commented May 31, 2022

@doberkofler for sure! next time if you could filter out the non-ts-eslint rules that'd go a long way.
I was super surprised when I couldn't open this issue at all this morning because it crashed the GH app AND chrome on my phone!
I'll file a bug with GH for that!


I understand and was actually thinking the same but when using const data = (await dataGetValidate({userid})) as Promise<dataType | null>; the rule '@typescript-eslint/no-misused-promises': ['error', {checksVoidReturn: false}] complains about Unnecessary parentheses around expression.

Your code should be

await (thing as Promise)

not

(await thing) as Promise

The former code you are "casting" it to a promise and then awaiting it (i.e. your result will be of type T from Promise<T>).
The latter code you are awaiting it and then "casting it to a promise (i.e. your result will be of type Promise<T>), which is incorrect.

Here's a playground to better show the correct parenthisation

@doberkofler
Copy link
Contributor Author

doberkofler commented May 31, 2022

@bradzacher I understand but when using the proper parentheses (sorry but I just copied the wrong code before) I get Unnecessary parentheses around expression. 8:22 - 8:23.

Example

@bradzacher
Copy link
Member

That's a bug in the @typescript-eslint/no-extra-parens lint rule!

@doberkofler
Copy link
Contributor Author

Thank you! Now I fully understand and sorry for not digging deeper before opening the SR. It seems I somehow just wanted it to be related to the improved no-misused-promises rule instead of actually checking the precedence rules ;-)

@doberkofler
Copy link
Contributor Author

Should I open a new SR or ... ?

@bradzacher
Copy link
Member

I just filed one on your behalf! #5124

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
fix: user error issue was fixed by correcting the configuration / correcting the code package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin working as intended Issues that are closed as they are working as intended
Projects
None yet
Development

No branches or pull requests

3 participants