diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 9e56c58411930..67599bccd2aba 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -672,9 +672,9 @@ namespace ts {
return moduleSpecifier && resolveExternalModuleName(moduleSpecifier, moduleSpecifier, /*ignoreErrors*/ true);
},
resolveExternalModuleSymbol,
- tryGetThisTypeAt: (nodeIn, includeGlobalThis) => {
+ tryGetThisTypeAt: (nodeIn, includeGlobalThis, container) => {
const node = getParseTreeNode(nodeIn);
- return node && tryGetThisTypeAt(node, includeGlobalThis);
+ return node && tryGetThisTypeAt(node, includeGlobalThis, container);
},
getTypeArgumentConstraint: nodeIn => {
const node = getParseTreeNode(nodeIn, isTypeNode);
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index a6121cddb6096..8e12a47c9f03c 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -4597,7 +4597,7 @@ namespace ts {
*/
/* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol;
/** @param node A location where we might consider accessing `this`. Not necessarily a ThisExpression. */
- /* @internal */ tryGetThisTypeAt(node: Node, includeGlobalThis?: boolean): Type | undefined;
+ /* @internal */ tryGetThisTypeAt(node: Node, includeGlobalThis?: boolean, container?: Node): Type | undefined;
/* @internal */ getTypeArgumentConstraint(node: TypeNode): Type | undefined;
/**
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 2f6b940f7cf7d..9e5ae92726972 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -2616,7 +2616,7 @@ namespace ts.Completions {
// Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== SyntaxKind.SourceFile) {
- const thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false);
+ const thisType = typeChecker.tryGetThisTypeAt(scopeNode, /*includeGlobalThis*/ false, isClassLike(scopeNode.parent) ? scopeNode : undefined);
if (thisType && !isProbablyGlobalType(thisType, sourceFile, typeChecker)) {
for (const symbol of getPropertiesForCompletion(thisType, typeChecker)) {
symbolToOriginInfoMap[symbols.length] = { kind: SymbolOriginInfoKind.ThisType };
diff --git a/tests/cases/fourslash/completionsThisPropertiesInPropertyDeclaration1.ts b/tests/cases/fourslash/completionsThisPropertiesInPropertyDeclaration1.ts
new file mode 100644
index 0000000000000..5de5f9abbae5a
--- /dev/null
+++ b/tests/cases/fourslash/completionsThisPropertiesInPropertyDeclaration1.ts
@@ -0,0 +1,28 @@
+///
+
+////class Foo {
+//// private _prop = 1;
+//// public a = [|_/*1*/|]
+////
+//// foo() {
+//// [|_/*2*/|]
+//// }
+////}
+
+verify.completions({
+ marker: ["1", "2"],
+ includes: [
+ {
+ name: "_prop",
+ insertText: "this._prop",
+ kind: "property",
+ sortText: completion.SortText.SuggestedClassMembers,
+ source: completion.CompletionSource.ThisProperty,
+ text: "(property) Foo._prop: number",
+ kindModifiers: "private"
+ },
+ ],
+ preferences: {
+ includeInsertTextCompletions: true
+ }
+});
diff --git a/tests/cases/fourslash/completionsThisPropertiesInPropertyDeclaration2.ts b/tests/cases/fourslash/completionsThisPropertiesInPropertyDeclaration2.ts
new file mode 100644
index 0000000000000..824b5f2855a62
--- /dev/null
+++ b/tests/cases/fourslash/completionsThisPropertiesInPropertyDeclaration2.ts
@@ -0,0 +1,28 @@
+///
+
+////class Foo {
+//// private static _prop = 1;
+//// public static a = [|_/*1*/|]
+////
+//// static foo() {
+//// [|_/*2*/|]
+//// }
+////}
+
+verify.completions({
+ marker: ["2"],
+ includes: [
+ {
+ name: "_prop",
+ insertText: "this._prop",
+ kind: "property",
+ sortText: completion.SortText.SuggestedClassMembers,
+ source: completion.CompletionSource.ThisProperty,
+ text: "(property) Foo._prop: number",
+ kindModifiers: "private,static"
+ },
+ ],
+ preferences: {
+ includeInsertTextCompletions: true
+ }
+});