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

Bug: [no-unnecessary-type-assertion] Does not flag on unnecessary nonnull assertion on declared value #8794

Open
4 tasks done
kirkwaiblinger opened this issue Mar 28, 2024 · 5 comments · May be fixed by #8901
Open
4 tasks done
Labels
accepting prs Go ahead, send a pull request that resolves this issue bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin

Comments

@kirkwaiblinger
Copy link
Member

kirkwaiblinger commented Mar 28, 2024

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=5.4.3&fileType=.ts&code=CYUwxgNghgTiAEYD2A7AzgF3gTwFzxQFcBbAIxBgG4AoZdJCEAOgiQHMAKbAQgEpKgA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6Jge1tiacTJTIAhtEK0ipWkOTJE0fJQ5N0UOdA7RI4MAF8QOoA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eFYDAruuGAL4g9A&tokens=false

Repro Code

declare const y: number;
console.log(y!);

ESLint Config

module.exports = {
  "rules": {
    "@typescript-eslint/no-unnecessary-type-assertion": "error"
  }
}

tsconfig

{
  "compilerOptions": {
    "strict": true
  }
}

Expected Result

I expect the second line to report an error.

Actual Result

No error.

Additional Info

The snippet

const y: number = 3;
console.log(y!);

flags as expected. For some reason just declare seems to mess it up.

@kirkwaiblinger kirkwaiblinger added bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for maintainers to take a look labels Mar 28, 2024
@bradzacher
Copy link
Member

This likely occurs because the rule has logic to determine if the non-null assertion is a "definite assignment" assertion.

Variables can be declared without a nullish type and not be assigned a value. When we inspect the type at the usage it is a non-nullish type. So a non-null assertion looks unnecessary, but it is actually necassery (removing it would be a type error).

@kirkwaiblinger
Copy link
Member Author

kirkwaiblinger commented Mar 29, 2024

@bradzacher

This likely occurs because the rule has logic to determine if the non-null assertion is a "definite assignment" assertion.

Variables can be declared without a nullish type and not be assigned a value. When we inspect the type at the usage it is a non-nullish type. So a non-null assertion looks unnecessary, but it is actually necassery (removing it would be a type error).

Oh, fascinating...... and a quick look in the code shows also that you've thought about this before, too :) microsoft/TypeScript#31124

Just to be clear, though, which of the following do you mean by your response?

  1. This behavior is a necessary tradeoff in order to handle let x!: number-type cases correctly
  2. This behavior is a fixable bug, that is probably caused by incorrect logic designed to handle let x!: number-type cases
  3. This behavior may or may not be fixable, investigation would be needed. A good starting point would be to look at the code that is designed to handle the let x!: number-type cases

@bradzacher
Copy link
Member

Cases like this is what I'm referring to

let x: number;
x!.toFixed();

playground

If you remove the non-null assertion then you get a TS error. This sort of code looks bad but there's usually a callback function between the assignment which TS's can't track.

@kirkwaiblinger
Copy link
Member Author

kirkwaiblinger commented Mar 29, 2024

Gotcha, yeah, so that seems clear to me, since that's literally a (tricky) case of a necessary nonnull assertion. Do you think, though, that that pattern would apply to variables declared with the declare keyword? I can't quite picture how it would translate.

@bradzacher
Copy link
Member

Based on some quick testing - no it does not apply to declare'd variables because those variables have no "potentially unassigned" state.

@bradzacher bradzacher added accepting prs Go ahead, send a pull request that resolves this issue and removed triage Waiting for maintainers to take a look labels Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepting prs Go ahead, send a pull request that resolves this issue bug Something isn't working package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin
Projects
None yet
2 participants