Skip to content

Union of string literals is incorrectly widened in error message when compared to never #41707

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

Closed
Aprillion opened this issue Nov 27, 2020 · 1 comment · Fixed by #59774
Closed
Labels
Bug A bug in TypeScript
Milestone

Comments

@Aprillion
Copy link

Aprillion commented Nov 27, 2020

TypeScript Version: 4.1.2, 4.0.5 (worked better in 3.9.7)

Search Terms: "string is not assignable to type never" (all 15 issues I found look slightly different I think)

Code

function assertUnreachable(_: never): void {}

type ActionTypes = 'a' | 'b'

function reducer(state: {}, action: {type: ActionTypes}) {
  switch(action.type) {
    case 'a':
      return state
    default: {
      assertUnreachable(action.type) // <-- incorrect widening on this line
      return state
    }
  }
}

Expected behavior: like in 3.9.7, the error message should be Argument of type '"b"' is not assignable to parameter of type 'never'

Actual behavior: Argument of type 'string' is not assignable to parameter of type 'never' - which is too wide to be actually helpful :(

Playground Link: https://www.typescriptlang.org/play?ts=4.1.2#code/GYVwdgxgLglg9mABAQwM6oKYCcoFUxYbIQAWyARgDYYAUA+gFyJgYBu2AlE63DACaIA3gF8AUKID0ExCFTIA5hlFQAngAcMiAILR4YACrqMqRAF5EAcmQXEAH0vkL40JFgJEhPiAjYaqKMhQGEwiADQougghqhpMOm4GRqjCHEKiiIioAO4wUKQ0xAkAdDEYqYLpGYgQaJpWFgyVVR4YUCBYSP6BSs18GMDIIJRQIU1VaJg4+ITEZFS0hXolRhxjGYRtHZkBQWNiGWJiohAIqHDURZRw8jSe3r5hQqVMFo4pHEA (change the version number to see the previous error)

Related Issues: ?

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Dec 2, 2020
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 2, 2020
@RyanCavanaugh RyanCavanaugh changed the title Union of string literals is widened incorrectly when compared to never Union of string literals is widened in error message when compared to never Dec 2, 2020
@RyanCavanaugh RyanCavanaugh changed the title Union of string literals is widened in error message when compared to never Union of string literals is incorrectly widened in error message when compared to never Dec 2, 2020
@hyzyla
Copy link
Contributor

hyzyla commented Aug 25, 2024

I've found a quick workaround for this problem for anyone who has the same issue:

Typescript Playground

// Use this literal instead of "never" to ensure that a switch statement is exhaustive.
// See issue: https://github.com/microsoft/TypeScript/issues/41707
type NeverStringLiteral = "__THIS_SHOULD_BE_UNREACHABLE__";

export function assertUnreachable(value: NeverStringLiteral): never {
  throw new Error(`Unreachable: ${value}`);
}

// usage
type ActionTypes = 'a' | 'b' | 'c'

function reducer(state: {}, action: {type: ActionTypes}) {
  switch(action.type) {
    case 'a':
      return state
    default: {
      // 🚫 Argument of type '"b" | "c"' is not assignable to parameter of type '"__THIS_SHOULD_BE_UNREACHABLE__"'
      assertUnreachable(action.type);
    }
  }
}

console.log(reducer({}, {type: 'b'}))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
@Aprillion @RyanCavanaugh @hyzyla and others