Skip to content

no type narrowing after if statement if function with return type never called inside #25542

@greg-hornby-roam

Description

@greg-hornby-roam

Tried my hardest to find if this was a duplicate error, so sorry if it is.

{
    let foo: string | number;
    if (typeof foo === "string") {
        throw "end";
    }
    foo; //Should Be: number; Is: number; Correct
}

In the code snippet above, it's correct that after the if statement, foo should be narrowed to type number, because if it is type string, then an error is thrown. However if abstracting the throw statement away into a function whose return type is never, the narrowing does not occur.

{
    let end = function(): never {
        throw "end";
    }
    let foo: string | number;
    if (typeof foo === "string") {
        end();
    }
    foo; //Should Be: number; Is: string | number; Incorrect
}

Playground Link: http://www.typescriptlang.org/play/#src=%7B%0D%0A%20%20%20%20let%20foo%3A%20string%20%7C%20number%3B%0D%0A%20%20%20%20if%20(typeof%20foo%20%3D%3D%3D%20%22string%22)%20%7B%0D%0A%20%20%20%20%20%20%20%20throw%20%22end%22%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20foo%3B%20%2F%2FShould%20Be%3A%20number%3B%20Is%3A%20number%3B%20Correct%0D%0A%7D%0D%0A%0D%0A%0D%0A%7B%0D%0A%20%20%20%20let%20end%20%3D%20function()%3A%20never%20%7B%0D%0A%20%20%20%20%20%20%20%20throw%20%22end%22%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20let%20foo%3A%20string%20%7C%20number%3B%0D%0A%20%20%20%20if%20(typeof%20foo%20%3D%3D%3D%20%22string%22)%20%7B%0D%0A%20%20%20%20%20%20%20%20end()%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20foo%3B%20%2F%2FShould%20Be%3A%20number%3B%20Is%3A%20string%20%7C%20number%3B%20Incorrect%0D%0A%7D

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