typescript-eslint / typescript-eslint

:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript
https://typescript-eslint.io
Other
15.33k stars 2.74k forks source link

Enhancement: [switch-exhaustiveness-check] support switching `true` #10241

Open Rusty-Beard opened 4 weeks ago

Rusty-Beard commented 4 weeks ago

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

Playground Link

https://typescript-eslint.io/play/#ts=5.6.2&fileType=.ts&code=MYewdgzgLgBBIFsCmA5ArggRkgTgLhjA2xxgF4YBGAbgChbRJYoloAxNMYS8mACgCUBIllzkAfDADetGHADuASyjAAFvyg40SAdJgB6fTCQAPAA5JgLACbGcOEKQBmjmFFVIYwNPaRhY2KoAhgBuio6ycl5BEJ7wyOiipGQpVHiRUTA4SFA%2BYFR0mdZITkFoADZQ6Zly2bk4%2BQBMhTAAvrTttPoAVLQABsAxnprafVlIZuVBwKwwAOTFpRVQczCYOEFcqgA0a2jMAJ4WEMA4imaw1iCsYHOwANZgIPIwQZgg%2B27BsLLd%2BgzgaBuVhQDhcRq8QTCYhiMiSKQwSIQJQqdR8EY6aQZaKxOCIVAw5KpSjVGp1PIFbGGVjlRT%2BAC01kUEDe5SQ9LApig9NpnJgAAEoEdWKdztyaXSoPonvTOJyZhAWTgDvTGEyoOEwNjBriMaTMuSGjBmpF2p0erQAMoWYCKJwHOkAcy%2BzLWGy2sygIEdOQ8pCU5XKePKIWGHle71DMDMDkwbIQu0wn2UXnATlpVggMBRqloguFJzOF3pEv80pAsrA8tYSpVauUmqyFSQv3%2BjCBLHYnGAAGZIUJCISJFi5MjlGoNFpMTJMjq4vjEiRyMT9VFDfkaPRZ0M3FOCNjFmVKqvajkKSa5GagA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6ZAd0vzIAt6AHrwCGsZPkoA3RExTJafRGQDW6KImjQA9tEgAacNjxFSyCtToNmbJltqwmssnOHRCCrUwAm3Sp7WQGtq6hgC%2BIKFAA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false

Repro Code

const someNumber: number = 1;
const testFunc = (): number => {
  switch (true) {
    case someNumber === 1:
      return 1;

    case true: 
    default:
      return 2;
  }
}

ESLint Config

module.exports = {
  parser: "@typescript-eslint/parser",
  rules: {
    "@typescript-eslint/switch-exhaustiveness-check": "error",
    "@typescript-eslint/no-unnecessary-condition": "error"
  },
};

tsconfig

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

Expected Result

considerDefaultExhaustiveForUnions option is implicitly enabled for switch (true) or switch (false) statements

Actual Result

It forces you to specify the case true branch with the disabled considerDefaultExhaustiveForUnions option (by default). At the same time, this conflicts with the no-unnecessary-condition rule.

Additional Info

No response

kirkwaiblinger commented 4 weeks ago

Hi @Rusty-Beard!

Is there a reason not to write this as

const someNumber: number = 1;
const testFunc = (): number => {
    if (someNumber === 1) {
        return 1;
    } else {
        return 2;
    }

I see that the lint rules are preventing you from writing each of the provided examples in the playground link... but I don't quite follow why any of them should be allowed.

OpportunityLiu commented 2 weeks ago

For reference, MDN told us to do so.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch#an_alternative_to_if...else_chains

Josh-Cena commented 2 weeks ago

For context I wrote that section. I mainly intended it as "here's something that's possible", and indeed it could be handy, especially if you need fallthrough. Part of my agenda was also to pursuade the TS team to implement better analysis for it since at that time there wasn't much control flow analysis specializing switch (true).

darcyrush commented 1 day ago

I just got bitten by this after updating.

I use switch (true) as a poor man's pattern matching. It makes switch statements really clean to write, especially if testing lots of different patterns for truth.