@@ -15170,8 +15170,41 @@ func (c *Checker) getWriteTypeOfSymbol(symbol *ast.Symbol) *Type {
15170
15170
}
15171
15171
15172
15172
func (c *Checker) GetTypeOfSymbolAtLocation(symbol *ast.Symbol, location *ast.Node) *Type {
15173
- // !!!
15174
- return c.getTypeOfSymbol(symbol)
15173
+ symbol = c.getExportSymbolOfValueSymbolIfExported(symbol)
15174
+ if location != nil {
15175
+ // If we have an identifier or a property access at the given location, if the location is
15176
+ // an dotted name expression, and if the location is not an assignment target, obtain the type
15177
+ // of the expression (which will reflect control flow analysis). If the expression indeed
15178
+ // resolved to the given symbol, return the narrowed type.
15179
+ if ast.IsIdentifier(location) || ast.IsPrivateIdentifier(location) {
15180
+ if isRightSideOfQualifiedNameOrPropertyAccess(location) {
15181
+ location = location.Parent
15182
+ }
15183
+ if ast.IsExpressionNode(location) && (!ast.IsAssignmentTarget(location) || isWriteAccess(location)) {
15184
+ var t *Type
15185
+ if isWriteAccess(location) && location.Kind == ast.KindPropertyAccessExpression {
15186
+ t = c.checkPropertyAccessExpression(location, CheckModeNormal, true /*writeOnly*/)
15187
+ } else {
15188
+ t = c.getTypeOfExpression(location)
15189
+ }
15190
+ if c.getExportSymbolOfValueSymbolIfExported(c.symbolNodeLinks.Get(location).resolvedSymbol) == symbol {
15191
+ return c.removeOptionalTypeMarker(t)
15192
+ }
15193
+ }
15194
+ }
15195
+ if ast.IsDeclarationName(location) && ast.IsSetAccessorDeclaration(location.Parent) && c.getAnnotatedAccessorTypeNode(location.Parent) != nil {
15196
+ return c.getWriteTypeOfAccessors(location.Parent.Symbol())
15197
+ }
15198
+ // The location isn't a reference to the given symbol, meaning we're being asked
15199
+ // a hypothetical question of what type the symbol would have if there was a reference
15200
+ // to it at the given location. Since we have no control flow information for the
15201
+ // hypothetical reference (control flow information is created and attached by the
15202
+ // binder), we simply return the declared type of the symbol.
15203
+ if isRightSideOfAccessExpression(location) && isWriteAccess(location.Parent) {
15204
+ return c.getWriteTypeOfSymbol(symbol)
15205
+ }
15206
+ }
15207
+ return c.getNonMissingTypeOfSymbol(symbol)
15175
15208
}
15176
15209
15177
15210
func (c *Checker) getTypeOfSymbol(symbol *ast.Symbol) *Type {
0 commit comments