Repository navigation
Experiment with tracking which entities actually may be narrowed #51525
Description
Activity
- addedSuggestionAn idea for TypeScriptAn idea for TypeScriptIn DiscussionNot yet reached consensusNot yet reached consensusDomain: PerformanceReports of unusually slow behaviorReports of unusually slow behavior
on Nov 14, 2022 I think the code in question for pyright was introduced in:
Wait, does TS walk the control flow graph backwards to discover narrowings? I always figured the graph looked something like
x = string | number->if (true) x = string->else x = numberand the compiler would know exactly which part of the tree it was in at the time it encountered a reference toxso it could just look up the current type directly.DanielRosenwasser commented
on Nov 14, 2022 MemberAuthorMore actionsIt does walk backwards. If it walked forwards, it would have to retain the context of all potential narrowing operations (and for all potential types we'd want to narrow from - which is occasionally necessary for things like narrowing constraints of generics rather than the generics themselves). That wouldn't work in our system where checking an expression should be as lazy as possible.
Anyway, in line with that, there are definitely opportunities for us to optimize here.
I guess that makes sense now that I think about it - there really aren't any "set the type to
string" style narrowings - eventypeof x === 'string'can narrow toneverif the original type doesn't overlap withstring. Otherwise you could probably do some kind of short-circuiting logic.- addedExperimentation NeededSomeone needs to try this out to see what happensSomeone needs to try this out to see what happensand removedIn DiscussionNot yet reached consensusNot yet reached consensus
on Nov 16, 2022 - added a commit that references this issue
on May 30, 2023 - addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on May 30, 2023 - addedRescheduledThis issue was previously scheduled to an earlier milestoneThis issue was previously scheduled to an earlier milestone
on Jul 26, 2024 - removedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Aug 20, 2026
In Pyright, narrowing can be avoided by keeping track of which entities actually get narrowed within a given scope. This could save a good amount of time by avoiding redundant walks up the control flow graph just to discover nothing interesting a given variable or property.
I'm not sure if Pyright also tracks the first location at which an entity may be narrowed, but that information could also be used to signal when a narrowing walk needs to stop.
This would come at the cost of some memory overhead, but we'd need to experiment to see what the trade-offs are.