Skip to content

Call to function returning never can not be used to narrow type #15991

Closed

Description

@bwrrp

TypeScript Version: 2.3.2

A function that never returns (return type never) can not be used in a type guard to narrow the type after the branch.

Code

class Thing { };

function diverges(): never {
    throw new Error('Never returns');
}

function problem(thing: Thing | null): Thing {
    if (thing === null) {
        diverges();
        // throw new Error('Works!');
    }

    return thing; // fails type check
}

Expected behavior:

Replacing the call to diverges() with a return or throw statement causes thing to be marked as type Thing after the branch, as code will never flow from the if (thing === null) branch to the code below. I expected a call to a function with return type never to achieve the same, as this should indicate that the call never returns.

Actual behavior:

The code does not compile due to an error, as the type of thing is not narrowed to Thing:
"Type 'Thing | null' is not assignable to type 'Thing'. Type 'null' is not assignable to type 'Thing'."

Activity

  1. krryan commented on May 22, 2017

    @krryan

    I suspect this won't happen, because it is possible to return a never-type value, which means it's possible for that function to complete and return and control to move on down to return thing;.

  2. RyanCavanaugh commented on May 22, 2017

    @RyanCavanaugh
    Member

    Duplicate #12825. The recommended workaround is to write return diverges();

  3. RyanCavanaugh commented on May 22, 2017

    @RyanCavanaugh
    Member

    I suspect this won't happen, because it is possible to return a never-type value

    The intent of never is that it shouldn't be possible.

  4. bwrrp commented on May 23, 2017

    @bwrrp
    ContributorAuthor

    Sorry, must have missed that one in my search. Thanks for the explanation!

  5. locked and limited conversation to collaborators on Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions