Skip to content
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

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

Closed
greg-hornby-roam opened this issue Jul 10, 2018 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@greg-hornby-roam
Copy link

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

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jul 10, 2018
@RyanCavanaugh
Copy link
Member

Duplicate #12825

@ajafff
Copy link
Contributor

ajafff commented Jul 10, 2018

TypeScript's control flow analysis cannot use type information, because type information is based on control flow. That would be a circular dependency.

I wrote a lint rule to enforce using return or throw when calling functions that return never: https://github.com/fimbullinter/wotan/blob/master/packages/mimir/docs/return-never-call.md
For a guide on how to use it, see this documentation: https://github.com/fimbullinter/wotan/blob/master/packages/wotan/README.md

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants