@@ -18,29 +18,22 @@ namespace ts.GoToDefinition {
1818 }
1919
2020 const typeChecker = program . getTypeChecker ( ) ;
21-
22- const calledDeclaration = tryGetSignatureDeclaration ( typeChecker , node ) ;
23- if ( calledDeclaration ) {
24- return [ createDefinitionFromSignatureDeclaration ( typeChecker , calledDeclaration ) ] ;
25- }
26-
27- let symbol = typeChecker . getSymbolAtLocation ( node ) ;
21+ const symbol = getSymbol ( node , typeChecker ) ;
2822
2923 // Could not find a symbol e.g. node is string or number keyword,
3024 // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
3125 if ( ! symbol ) {
3226 return getDefinitionInfoForIndexSignatures ( node , typeChecker ) ;
3327 }
3428
35- // If this is an alias, and the request came at the declaration location
36- // get the aliased symbol instead. This allows for goto def on an import e.g.
37- // import {A, B} from "mod";
38- // to jump to the implementation directly.
39- if ( symbol . flags & SymbolFlags . Alias && shouldSkipAlias ( node , symbol . declarations [ 0 ] ) ) {
40- const aliased = typeChecker . getAliasedSymbol ( symbol ) ;
41- if ( aliased . declarations ) {
42- symbol = aliased ;
43- }
29+ const calledDeclaration = tryGetSignatureDeclaration ( typeChecker , node ) ;
30+ if ( calledDeclaration ) {
31+ const sigInfo = createDefinitionFromSignatureDeclaration ( typeChecker , calledDeclaration ) ;
32+ // For a function, if this is the original function definition, return just sigInfo.
33+ // If this is the original constructor definition, parent is the class.
34+ return typeChecker . getRootSymbols ( symbol ) . some ( s => calledDeclaration . symbol === s || calledDeclaration . symbol . parent === s )
35+ ? [ sigInfo ]
36+ : [ sigInfo , ...getDefinitionFromSymbol ( typeChecker , symbol , node ) ] ;
4437 }
4538
4639 // Because name in short-hand property assignment has two different meanings: property name and property value,
@@ -158,6 +151,21 @@ namespace ts.GoToDefinition {
158151 } ) ;
159152 }
160153
154+ function getSymbol ( node : Node , checker : TypeChecker ) : Symbol | undefined {
155+ const symbol = checker . getSymbolAtLocation ( node ) ;
156+ // If this is an alias, and the request came at the declaration location
157+ // get the aliased symbol instead. This allows for goto def on an import e.g.
158+ // import {A, B} from "mod";
159+ // to jump to the implementation directly.
160+ if ( symbol && symbol . flags & SymbolFlags . Alias && shouldSkipAlias ( node , symbol . declarations [ 0 ] ) ) {
161+ const aliased = checker . getAliasedSymbol ( symbol ) ;
162+ if ( aliased . declarations ) {
163+ return aliased ;
164+ }
165+ }
166+ return symbol ;
167+ }
168+
161169 // Go to the original declaration for cases:
162170 //
163171 // (1) when the aliased symbol was declared in the location(parent).
0 commit comments