diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts
index 33330d1d0b0..e1ea158f138 100644
--- a/src/services/goToDefinition.ts
+++ b/src/services/goToDefinition.ts
@@ -51,7 +51,8 @@ namespace ts.GoToDefinition {
// assignment. This case and others are handled by the following code.
if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) {
const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
- return shorthandSymbol ? shorthandSymbol.declarations.map(decl => createDefinitionInfo(decl, typeChecker, shorthandSymbol, node)) : [];
+ const definitions = shorthandSymbol ? shorthandSymbol.declarations.map(decl => createDefinitionInfo(decl, typeChecker, shorthandSymbol, node)) : emptyArray;
+ return concatenate(definitions, getDefinitionFromObjectLiteralElement(typeChecker, node) || emptyArray);
}
// If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
@@ -75,25 +76,7 @@ namespace ts.GoToDefinition {
});
}
- // If the current location we want to find its definition is in an object literal, try to get the contextual type for the
- // object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
- // For example
- // interface Props{
- // /*first*/prop1: number
- // prop2: boolean
- // }
- // function Foo(arg: Props) {}
- // Foo( { pr/*1*/op1: 10, prop2: true })
- const element = getContainingObjectLiteralElement(node);
- if (element) {
- const contextualType = element && typeChecker.getContextualType(element.parent);
- if (contextualType) {
- return flatMap(getPropertySymbolsFromContextualType(element, typeChecker, contextualType, /*unionSymbolOk*/ false), propertySymbol =>
- getDefinitionFromSymbol(typeChecker, propertySymbol, node));
- }
- }
-
- return getDefinitionFromSymbol(typeChecker, symbol, node);
+ return getDefinitionFromObjectLiteralElement(typeChecker, node) || getDefinitionFromSymbol(typeChecker, symbol, node);
}
/**
@@ -108,6 +91,26 @@ namespace ts.GoToDefinition {
|| (!isCallLikeExpression(calledDeclaration.parent) && s === calledDeclaration.parent.symbol);
}
+ // If the current location we want to find its definition is in an object literal, try to get the contextual type for the
+ // object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
+ // For example
+ // interface Props{
+ // /*first*/prop1: number
+ // prop2: boolean
+ // }
+ // function Foo(arg: Props) {}
+ // Foo( { pr/*1*/op1: 10, prop2: true })
+ function getDefinitionFromObjectLiteralElement(typeChecker: TypeChecker, node: Node) {
+ const element = getContainingObjectLiteralElement(node);
+ if (element) {
+ const contextualType = element && typeChecker.getContextualType(element.parent);
+ if (contextualType) {
+ return flatMap(getPropertySymbolsFromContextualType(element, typeChecker, contextualType, /*unionSymbolOk*/ false), propertySymbol =>
+ getDefinitionFromSymbol(typeChecker, propertySymbol, node));
+ }
+ }
+ }
+
export function getReferenceAtPosition(sourceFile: SourceFile, position: number, program: Program): { reference: FileReference, file: SourceFile } | undefined {
const referencePath = findReferenceInPosition(sourceFile.referencedFiles, position);
if (referencePath) {
diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty04.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty04.ts
new file mode 100644
index 00000000000..4f24a9aef76
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionShorthandProperty04.ts
@@ -0,0 +1,11 @@
+///
+
+////interface Foo {
+//// /*2*/foo(): void
+////}
+////
+////let x: Foo = {
+//// [|f/*1*/oo|]
+////}
+
+verify.goToDefinition("1", "2");
diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty05.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty05.ts
new file mode 100644
index 00000000000..d00036ca381
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionShorthandProperty05.ts
@@ -0,0 +1,11 @@
+///
+
+////interface Foo {
+//// /*3*/foo(): void
+////}
+////const /*2*/foo = 1;
+////let x: Foo = {
+//// [|f/*1*/oo|]
+////}
+
+verify.goToDefinition("1", ["2", "3"]);
diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty06.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty06.ts
new file mode 100644
index 00000000000..8fe36acdff7
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionShorthandProperty06.ts
@@ -0,0 +1,11 @@
+///
+
+////interface Foo {
+//// /*2*/foo(): void
+////}
+////const foo = 1;
+////let x: Foo = {
+//// [|f/*1*/oo|]()
+////}
+
+verify.goToDefinition("1", "2");