diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts
index 40cac0a916d..866588c51b9 100644
--- a/src/services/goToDefinition.ts
+++ b/src/services/goToDefinition.ts
@@ -171,13 +171,15 @@ namespace ts.GoToDefinition {
if (!baseDeclaration) return;
const baseTypeNode = getEffectiveBaseTypeNode(baseDeclaration);
- const baseType = baseTypeNode ? typeChecker.getTypeAtLocation(baseTypeNode) : undefined;
- if (!baseType) return;
+ if (!baseTypeNode) return;
+ const expression = skipParentheses(baseTypeNode.expression);
+ const base = isClassExpression(expression) ? expression.symbol : typeChecker.getSymbolAtLocation(expression);
+ if (!base) return;
const name = unescapeLeadingUnderscores(getTextOfPropertyName(classElement.name));
const symbol = hasStaticModifier(classElement)
- ? typeChecker.getPropertyOfType(typeChecker.getTypeOfSymbolAtLocation(baseType.symbol, baseDeclaration), name)
- : typeChecker.getPropertyOfType(baseType, name);
+ ? typeChecker.getPropertyOfType(typeChecker.getTypeOfSymbol(base), name)
+ : typeChecker.getPropertyOfType(typeChecker.getDeclaredTypeOfSymbol(base), name);
if (!symbol) return;
return getDefinitionFromSymbol(typeChecker, symbol, node);
diff --git a/src/services/utilities.ts b/src/services/utilities.ts
index 4d24e57d051..58d1b1cbca1 100644
--- a/src/services/utilities.ts
+++ b/src/services/utilities.ts
@@ -790,6 +790,8 @@ namespace ts {
}
export function getContextualTypeFromParentOrAncestorTypeNode(node: Expression, checker: TypeChecker): Type | undefined {
+ if (node.flags & (NodeFlags.JSDoc & ~NodeFlags.JavaScriptFile)) return undefined;
+
const contextualType = getContextualTypeFromParent(node, checker);
if (contextualType) return contextualType;
diff --git a/tests/baselines/reference/findAllRefsForStringLiteral.baseline.jsonc b/tests/baselines/reference/findAllRefsForStringLiteral.baseline.jsonc
new file mode 100644
index 00000000000..5cfaa3f509c
--- /dev/null
+++ b/tests/baselines/reference/findAllRefsForStringLiteral.baseline.jsonc
@@ -0,0 +1,52 @@
+// === /a.ts ===
+// interface Foo {
+// property: /*FIND ALL REFS*/"[|foo|]";
+// }
+// /**
+// * @type {{ property: "foo"}}
+// */
+// const obj: Foo = {
+// property: "[|foo|]",
+// }
+
+[
+ {
+ "definition": {
+ "containerKind": "",
+ "containerName": "",
+ "fileName": "/a.ts",
+ "kind": "var",
+ "name": "foo",
+ "textSpan": {
+ "start": 31,
+ "length": 3
+ },
+ "displayParts": [
+ {
+ "text": "\"foo\"",
+ "kind": "stringLiteral"
+ }
+ ]
+ },
+ "references": [
+ {
+ "textSpan": {
+ "start": 31,
+ "length": 3
+ },
+ "fileName": "/a.ts",
+ "isWriteAccess": false,
+ "isInString": true
+ },
+ {
+ "textSpan": {
+ "start": 111,
+ "length": 3
+ },
+ "fileName": "/a.ts",
+ "isWriteAccess": false,
+ "isInString": true
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/tests/baselines/reference/renameForStringLiteral.baseline b/tests/baselines/reference/renameForStringLiteral.baseline
new file mode 100644
index 00000000000..9e915526960
--- /dev/null
+++ b/tests/baselines/reference/renameForStringLiteral.baseline
@@ -0,0 +1,11 @@
+/*====== /a.ts ======*/
+
+interface Foo {
+ property: "RENAME";
+}
+/**
+ * @type {{ property: "foo"}}
+ */
+const obj: Foo = {
+ property: "RENAME",
+}
diff --git a/tests/cases/fourslash/findAllRefsForStringLiteral.ts b/tests/cases/fourslash/findAllRefsForStringLiteral.ts
new file mode 100644
index 00000000000..d7a3e92943d
--- /dev/null
+++ b/tests/cases/fourslash/findAllRefsForStringLiteral.ts
@@ -0,0 +1,14 @@
+///
+
+// @filename: /a.ts
+////interface Foo {
+//// property: /**/"foo";
+////}
+/////**
+//// * @type {{ property: "foo"}}
+//// */
+////const obj: Foo = {
+//// property: "foo",
+////}
+
+verify.baselineFindAllReferences("");
diff --git a/tests/cases/fourslash/goToDefinitionOverriddenMember16.ts b/tests/cases/fourslash/goToDefinitionOverriddenMember16.ts
new file mode 100644
index 00000000000..96f1467a344
--- /dev/null
+++ b/tests/cases/fourslash/goToDefinitionOverriddenMember16.ts
@@ -0,0 +1,16 @@
+///
+// @Filename: goToDefinitionOverrideJsdoc.ts
+// @allowJs: true
+// @checkJs: true
+
+//// export class C extends CompletelyUndefined {
+//// /**
+//// * @override/*1*/
+//// * @returns {{}}
+//// */
+//// static foo() {
+//// return {}
+//// }
+//// }
+
+verify.goToDefinition(['1'], [])
diff --git a/tests/cases/fourslash/renameForStringLiteral.ts b/tests/cases/fourslash/renameForStringLiteral.ts
new file mode 100644
index 00000000000..5d35ded522a
--- /dev/null
+++ b/tests/cases/fourslash/renameForStringLiteral.ts
@@ -0,0 +1,14 @@
+///
+
+// @filename: /a.ts
+////interface Foo {
+//// property: /**/"foo";
+////}
+/////**
+//// * @type {{ property: "foo"}}
+//// */
+////const obj: Foo = {
+//// property: "foo",
+////}
+
+verify.baselineRename("", {});