From 4fc4c18299dbaa2e1be95da62a7aa689c15e4eea Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 5 Aug 2021 22:40:20 -0700 Subject: [PATCH] Fix completions in return when in function with contextual 'this' (#45340) --- src/services/completions.ts | 6 ++++ ...ompletionListInReturnWithContextualThis.ts | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/cases/fourslash/completionListInReturnWithContextualThis.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index a762645ea6d..285095e727a 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1602,6 +1602,12 @@ namespace ts.Completions { } if (!isTypeLocation) { + // GH#39946. Pulling on the type of a node inside of a function with a contextual `this` parameter can result in a circularity + // if the `node` is part of the exprssion of a `yield` or `return`. This circularity doesn't exist at compile time because + // we will check (and cache) the type of `this` *before* checking the type of the node. + const container = getThisContainer(node, /*includeArrowFunctions*/ false); + if (!isSourceFile(container) && container.parent) typeChecker.getTypeAtLocation(container); + let type = typeChecker.getTypeAtLocation(node).getNonOptionalType(); let insertQuestionDot = false; if (type.isNullableType()) { diff --git a/tests/cases/fourslash/completionListInReturnWithContextualThis.ts b/tests/cases/fourslash/completionListInReturnWithContextualThis.ts new file mode 100644 index 00000000000..3dfbf576733 --- /dev/null +++ b/tests/cases/fourslash/completionListInReturnWithContextualThis.ts @@ -0,0 +1,31 @@ +/// + +////interface Ctx { +//// foo(): { +//// x: number +//// }; +////} +//// +////declare function wrap(cb: (this: Ctx) => any): void; +//// +////wrap(function () { +//// const xs = this.foo(); +//// return xs./*inReturn*/ +////}); +//// +////wrap(function () { +//// const xs = this.foo(); +//// const y = xs./*involvedInReturn*/ +//// return y; +////}); + +verify.completions( + { + marker: "inReturn", + exact: ["x"], + }, + { + marker: "involvedInReturn", + exact: ["x"], + }, +);