question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

narrowing in switch doesn't work with non-union types

See original GitHub issue
class A {
    readonly kind = 'a';
}
type U = A; // <-- supposed to be a single case union
declare var u: U;
declare function never(never: never): never;
function fn() {
    switch (u.kind) {
        case 'a': return 1;
        default: return never(u); // <-- u expected to be never, actually is A
    }
}

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:6
  • Comments:12 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
zpdDG4gta8XKpMCdcommented, Aug 7, 2017

interestingly narrowing works for single string literals, which is at very least looks inconsistent with this very issue

type U = 'a'; // <-- supposed to be a single case union
declare var u: U;
declare function never(never: never): never;
function fn() {
    switch (u) {
        case 'a': return 1;
        default: return never(u); // <-- WORKS!
    }
}
1reaction
Freak613commented, Mar 3, 2021

@RyanCavanaugh,

Can be useful when designing API that don’t have union initially, but later got it:

// Initial
{
  type DbError = {
    tag: "DbError"
  }

  const updateDB = (onError: (error: DbError) => void) => { }

  updateDB(error => {
    switch (error.tag) {
      case "DbError":
        const e1: DbError = error;
        console.log("DbError happened");
        break;
      default:
        // Problem, all possible errors are handled
        const e2: never = error; // Type 'DbError' is not assignable to type 'never'.
        console.log("Unhandled error");
        break;
    }
  })
}

// Sometimes later
{
  type DbError = {
    tag: "DbError"
  }

  type NewDbError = {
    tag: "NewDbError"
  }

  const updateDB = (onError: (error: DbError | NewDbError) => void) => { }

  updateDB(error => {
    switch (error.tag) {
      case "DbError":
        const e1: DbError = error;
        console.log("DbError happened");
        break;
      default:
        // Correct, need to update code to handle new error type
        const e2: never = error; // Type 'NewDbError' is not assignable to type 'never'.
        console.log("Unhandled error");
        break;
    }
  })
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript 3.8.3 not narrowing union type in switch statement
I notice that from TS 4.3.5 and on, the type is narrowed the way I'd expect (the error disappears), but I can't change...
Read more >
narrowing types via type guards and assertion functions - 2ality
The problem in this case is that, without narrowing, we can't access property .second of a value whose type is FirstOrSecond . The...
Read more >
Malunions and Nonunions: Penn Medicine's Samir Mehta, MD ...
Four Factors for Fracture Healing. Typically, the reasons an injury did not properly heal can be narrowed down quickly. "Usually, the problem is ......
Read more >
9 strategies for narrowing the gender pay gap | MoneyUnder30
Strategies to narrow the gender pay gap include promoting pay transparency, expanding paid family and medical leave, and improving work-life ...
Read more >
Spinal Deformity: Adult Degenerative Scoliosis - Mayfield Clinic
Types of spinal deformities: a side-to-side curve is called scoliosis; ... Simply removing material from the spine can cause a problem down the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found