Skip to content

! type assertion on never changes the type #35431

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
Skalman opened this issue Nov 30, 2019 · 2 comments · Fixed by #35863
Closed

! type assertion on never changes the type #35431

Skalman opened this issue Nov 30, 2019 · 2 comments · Fixed by #35863
Labels
Bug A bug in TypeScript
Milestone

Comments

@Skalman
Copy link

Skalman commented Nov 30, 2019

TypeScript Version: 3.8.0-dev.20191128

Search Terms: ! type assertion, never, wrong type

Code

type A = { kind: "abc" } | { kind: "def" };

function f(a: A) {
  switch (a.kind) {
    case "abc":
      return 1;
    case "def":
      return 2;
    default:
      throw new Error("Bad kind: " + a!?.kind);
      // Hover over `a`:             ^
  }
}

Expected behavior:

Hovering gives the type never.

Actual behavior:

Hovering gives the type A.

Playground Link: The TS playground doesn't work for me

Related Issues: typescript-eslint/typescript-eslint#1282


More context: This is a problem for TypeScript ESLint's "no-unnecessary-type-assertion" rule, which relies on the ! operator not changing the type of the underlying expression.
(@bradzacher, please correct me if I'm misrepresenting anything.)

In the following example, hovering the as always gives the same type:

declare const a: { kind: string } | undefined;

console.log(a!?.kind);
console.log(a?.kind);
@bradzacher
Copy link
Contributor

Note - it appears that this only seems to happen with the nevers

type A = { kind: "abc" } | { kind: "def" };

function f(a: A) {
  switch (a.kind) {
    case "abc":
      return 1;
    case "def":
      return 2;
    default:
      throw new Error("Bad kind: " + a.kind);
      throw new Error("Bad kind: " + a!.kind);
  }
}

Best shown in the ts-ast-viewer:

Inspecting the two a identifiers:

  • In the first case (line 10, the one without the !), the API reports the type of the identifier a as never
    image

  • In the second case (line 11, the one with the !), the API reports the type of the identifier a as A
    image

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Dec 2, 2019
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 2, 2019
@RyanCavanaugh
Copy link
Member

There's some sketchy logic in getFlowTypeOfReference that's happening when it shouldn't.

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
3 participants