diff --git a/tsc/internal/checker/flow.go b/tsc/internal/checker/flow.go index d2831231772fe..4967fcbe4ec16 100644 --- a/tsc/internal/checker/flow.go +++ b/tsc/internal/checker/flow.go @@ -1610,8 +1610,19 @@ func (c *Checker) isMatchingReference(source *ast.Node, target *ast.Node) bool { if ast.IsThisInTypeQuery(source) { return target.Kind == ast.KindThisKeyword } - return ast.IsIdentifier(target) && c.getResolvedSymbol(source) == c.getResolvedSymbol(target) || - (ast.IsVariableDeclaration(target) || ast.IsBindingElement(target)) && c.getExportSymbolOfValueSymbolIfExported(c.getResolvedSymbol(source)) == c.getSymbolOfDeclaration(target) + if ast.IsIdentifier(target) { + return c.getResolvedSymbol(source) == c.getResolvedSymbol(target) + } + if ast.IsVariableDeclaration(target) || ast.IsBindingElement(target) { + // A declaration's symbol is named by its identifier, so a reference with a + // different name cannot resolve to it. Checking names first avoids loading + // the symbols of every unrelated declaration seen while walking flow nodes. + if name := target.Name(); name != nil && ast.IsIdentifier(name) && name.AsIdentifier().Text != source.Text() { + return false + } + return c.getExportSymbolOfValueSymbolIfExported(c.getResolvedSymbol(source)) == c.getSymbolOfDeclaration(target) + } + return false case ast.KindThisKeyword: return target.Kind == ast.KindThisKeyword case ast.KindSuperKeyword: