Skip to content

[no-fallthrough] Lint rule needs type information to avoid false positives e.g. nested switch #3455

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

Open
3 tasks done
OliverJAsh opened this issue May 28, 2021 · 6 comments
Open
3 tasks done
Labels
accepting prs Go ahead, send a pull request that resolves this issue enhancement: new base rule extension New base rule extension required to handle a TS specific case package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin

Comments

@OliverJAsh
Copy link
Contributor

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have read the FAQ and my problem is not listed.

Repro

{
  "rules": {
    "no-fallthrough": [2]
  }
}
declare const n: { a: 1; b: 1 | 2 } | { a: 2 };
(() => {
  switch (n.a) {
    case 1: {
      switch (n.b) {
        case 1:
          return 1;
        case 2:
          return 1;
      }
    }
    // ESLint error:
    // Expected a 'break' statement before 'case'.
    case 2: {
      return 2;
    }
  }
})();

Expected Result

No lint error

Actual Result

Lint error (see comment)

Additional Info

I think the TS ESLint plugin needs to provide its own version of no-fallthrough in order to take advantage of type information so we can avoid false positives such as this.

Versions

package version
@typescript-eslint/eslint-plugin latest
@typescript-eslint/parser latest
TypeScript latest
ESLint latest
node latest
@OliverJAsh OliverJAsh added package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for team members to take a look labels May 28, 2021
@bradzacher bradzacher added enhancement: new base rule extension New base rule extension required to handle a TS specific case and removed triage Waiting for team members to take a look labels May 28, 2021
@BobNobrain
Copy link

Another example of code with false positive no-fallthrough error due to lack of information about types:

switch(x) {
    case 0:
        process.exit(0);
        // putting `break` here silents no-fallthrough, but causes unreachable code warning from ts

    default:
        // ...
}

@JoshuaKGoldberg JoshuaKGoldberg added the accepting prs Go ahead, send a pull request that resolves this issue label Oct 25, 2021
@wclr
Copy link

wclr commented Feb 5, 2022

Wanted to make new rule proposal but then found this. So core no-fallthrough requires an unneeded break, even if a nested switch case is exhaustive. But exhaustiveness of the case can be detected only with types.

Such code with core `no-fallthrough enabled requires unneeded break:

const fn = (x: "A" | "B", n: "Err" | "Ok"): number => {
  switch (x) {
    case "A":
      switch (n) {
        case "Ok":
          return 1
        
        case "Err":
          return 0  
        
      }
    break; // this break actually not needed with typescript 
    default:
      return -1
  }
}

image

TS config actually has the option noFallthroughCasesInSwitch, which almost checks the same thing, but error reporting is a bit scarce.

@dani-mp
Copy link

dani-mp commented Sep 28, 2023

Had this problem today with a nested switch. The formatter removes the unnecessary breaks. And eslint complains about them being expected.

@bradzacher
Copy link
Member

The difficulty with building this out will be the interaction between both types and control-flow analysis.
This is definitely going to be a REALLY complicated rule for someone to build and you'll need to dig into some pretty gnarly parts of TS's APIs to get this working properly.

TS does have noFallthroughCasesInSwitch, though I don't know how it compares to the lint rule.

@pcone
Copy link

pcone commented Jun 4, 2025

I don't think fixing this by changing typescript-eslint to allow the missing break statements is a good idea. This just introduces a footgun for code without 100% accurate typing, incorrect/missing data validation etc because we have no way of knowing for sure if the switch case statements will actually be exhaustive at runtime.

The safer and imo better fix here would be for Typescripts compile time error to allow for break statements in supposedly unreachable code somehow.

@kirkwaiblinger
Copy link
Member

kirkwaiblinger commented Jun 4, 2025

The safer and imo better fix here would be for Typescripts compile time error to allow for break statements in supposedly unreachable code somehow.

Honestly not a crazy use of a TS error suppression

switch (foo) {
  case bar: 
    neverReturningFunction()
    // @ts-expect-error -- ensure this branch is syntactically guaranteed to terminate
    break;
}

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 enhancement: new base rule extension New base rule extension required to handle a TS specific case package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin
Projects
None yet
Development

No branches or pull requests

8 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy