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-condition] Unnecessary conditional when trying to use coalesce operator on null | undefined #10055

Closed
4 tasks done
darkbasic opened this issue Sep 25, 2024 · 8 comments
Labels
bug Something isn't working locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin working as intended Issues that are closed as they are working as intended

Comments

@darkbasic
Copy link

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.5.2&fileType=.tsx&code=GYVwdgxgLglg9mABAWwJ4DFwQBQEMBOA5gFyJggA2FiAPouACYCmwMYTDAlKYy2x4gDeAKESJ8TKCHxIChRAH4F9MM1bsGwgL5A&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6Jge1tiacTJTIAhtEK0yHJgBNK%2BSpPRgA2uGyRE0aB2iQANKuyYDaofHgcA7gGFJyfEJYAZDh2I3ps%2BU1QZ8cRMYQAL7GALqqIUFAA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false

Repro Code

function myFunc(arg: null | undefined): undefined {
  return arg ?? undefined
}

ESLint Config

module.exports = {
  parser: "@typescript-eslint/parser",
  rules: {
    "@typescript-eslint/no-unnecessary-condition": [
    "error",
      {
      "allowConstantLoopConditions": true
      }
    ]
  },
};

tsconfig

{
  "compilerOptions": {
    "strictNullChecks": true
  }
}

Expected Result

arg ?? undefined limits the union type null | undefined to just undefined so it's not unnecessary.

Actual Result

arg ?? undefined errors out like if it didn't restrict the union type a subset of its values.

Additional Info

No response

@darkbasic darkbasic 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 Sep 25, 2024
@kirkwaiblinger
Copy link
Member

The rule is trying to point out that you could write this like

function myFunc(arg: null | undefined): undefined {
  return undefined
}

it reports both always-true and always-false conditions as unnecessary, too, like

declare const alwaysTrue: true;
declare const alwaysFalse: false;
// reported by the rule
if (alwaysTrue) {
}
// reported by the rule
if (alwaysFalse) {
}

@kirkwaiblinger kirkwaiblinger added awaiting response Issues waiting for a reply from the OP or another party and removed triage Waiting for team members to take a look labels Sep 25, 2024
@darkbasic
Copy link
Author

Makes sense. My bad but I'm in the process of refactoring a big codebase with eslint-config-love and I'm a bit overflowed by over-reaching rules right now :)

@darkbasic
Copy link
Author

@kirkwaiblinger sorry for reusing the same issue but I've also noticed the following:

let api: Axios

export function useApi(options: AxiosRequestConfig = {}): Axios {
  // Unnecessary conditional, the types have no overlap.eslint[@typescript-eslint/no-unnecessary-condition]
  if (api == null) {
    createApi(options)
  }
  return api
}

Typescript should be able to notice that no value has been assigned for certain to api and thus it can be undefined, right?

@kirkwaiblinger
Copy link
Member

Ah - this is a pet peeve of mine - see #9565.

In short - no. let x: Axios means "x will be defined by the time I use it in a closure" and let x: Axios | undefined means "x may or may not be defined by the time it's accessed". This is a textbook case of where you must use let x: Axios | undefined in order to get correct types.

@kirkwaiblinger
Copy link
Member

For future reference, these sort of general usage/support questions are best asked in our discord server 🙂

@kirkwaiblinger
Copy link
Member

In short - no.

Or, rather - it should complain, but it doesn't! 😆

(note that I have yet to file the TS issue that I intended to file)

@kirkwaiblinger kirkwaiblinger added working as intended Issues that are closed as they are working as intended and removed awaiting response Issues waiting for a reply from the OP or another party labels Sep 25, 2024
@kirkwaiblinger kirkwaiblinger closed this as not planned Won't fix, can't repro, duplicate, stale Sep 25, 2024
@darkbasic
Copy link
Author

darkbasic commented Sep 25, 2024

it should complain, but it doesn't!

Oh that explains why they recently enabled init-declarations in eslint-love: if you're forced to declared a variable as undefined you will be forced to add undefined to the union as well. I sometimes tend to give Typescript more credit than it deserves: I would have bet that it was capable of determining if a variable has been assigned or not by the time it's being accessed :(

EDIT: apparently I was wrong about that:
image

note that I have yet to file the TS issue that I intended to file

Too bad, I would have added it to my (very long) list of Typescript issues I follow :)

For future reference, these sort of general usage/support questions are best asked in our discord server

Sure, thanks!

@kirkwaiblinger
Copy link
Member

@darkbasic Opened it! microsoft/TypeScript#60064 Thanks for the nudge 🙂

@github-actions github-actions bot added the locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. label Oct 3, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. 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

2 participants