-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Calling a function that returns never isn't treated as stopping control flow #32677
Comments
Duplicate of #16546, more or less. |
Ah, didn't find that. But that one wasn't ever resolved and closed for housekeeping reasons. The Is there a technical reason for the way this currently works? |
One thing that the above linked comment doesn’t mention is that the control flow graph is constructed before type information is available, so effectively this would require every single function call to be added to it. As you can imagine that would be prohibitively expensive to do. |
It sorta does, just not in those words.
|
That’s misleading though because if the return type is explicitly annotated then it’s part of the AST (and therefore still syntactical). TS just hasn’t constructed the necessary type information internally for that to matter. |
I, for one, would be perfectly satisfied with this only working for functions explicitly annotated to return |
@marijnh yes it would still have the same performance issues. At the time the control flow graph is created the compiler does not know the return type of a function, it just sees a call. So you either include all calls in the graph or no calls. All you can use to decide if a node is to be included is the syntax. |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
EDIT: Apparently this happens as otherwise it would make CFA too expensive performance wise. Now that we have #32695 - I wasn't expecting a different between the following two snippets: function throws(): never {
throw new Error();
}
throws();
console.log('here'); // ⚠ unreachable code detected However: function throws(): never {
throw new Error();
}
let n: string = throws();
console.log(n); // considered reachable Is there somewhere that details why this is? ( I understand why 'never' is assignable to 'string', more about why the code is considered reachable). EDIT: It is for performance reasons, to reduce the number of function calls that are also CFA nodes |
Code
Expected behavior:
I would expect the control flow analysis to treat the
console.log
as only being reachable if theif
branch wasn't taken, which means thatx
is a number, so the code is accepted. This does happen when you inline thethrow
.Actual behavior:
The type of
x
isn't narrowed and an error is reported forx * 2
.Playground Link: here
The text was updated successfully, but these errors were encountered: