Skip to content

Commit 64d01d8

Browse files
Provide a better error on arrow functions that capture the global 'this'.
1 parent 3057be3 commit 64d01d8

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15279,7 +15279,7 @@ namespace ts {
1527915279
// Stop at the first arrow function so that we can
1528015280
// tell whether 'this' needs to be captured.
1528115281
let container = getThisContainer(node, /* includeArrowFunctions */ true);
15282-
let needToCaptureLexicalThis = false;
15282+
let capturedByArrowFunction = false;
1528315283

1528415284
if (container.kind === SyntaxKind.Constructor) {
1528515285
checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
@@ -15288,9 +15288,7 @@ namespace ts {
1528815288
// Now skip arrow functions to get the "real" owner of 'this'.
1528915289
if (container.kind === SyntaxKind.ArrowFunction) {
1529015290
container = getThisContainer(container, /* includeArrowFunctions */ false);
15291-
15292-
// When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code
15293-
needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES2015);
15291+
capturedByArrowFunction = true;
1529415292
}
1529515293

1529615294
switch (container.kind) {
@@ -15320,14 +15318,19 @@ namespace ts {
1532015318
break;
1532115319
}
1532215320

15323-
if (needToCaptureLexicalThis) {
15321+
// When targeting es6, mark that we'll need to capture `this` in its lexically bound scope.
15322+
if (capturedByArrowFunction && languageVersion < ScriptTarget.ES2015) {
1532415323
captureLexicalThis(node, container);
1532515324
}
1532615325

1532715326
const type = tryGetThisTypeAt(node, container);
1532815327
if (!type && noImplicitThis) {
1532915328
// With noImplicitThis, functions may not reference 'this' if it has type 'any'
15330-
error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
15329+
error(
15330+
node,
15331+
capturedByArrowFunction ?
15332+
Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation :
15333+
Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this_which_implicitly_has_type_any);
1533115334
}
1533215335
return type || anyType;
1533315336
}

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,6 +3921,10 @@
39213921
"category": "Error",
39223922
"code": 7040
39233923
},
3924+
"The containing arrow function captures the global value of 'this' which implicitly has type 'any'.": {
3925+
"category": "Error",
3926+
"code": 7041
3927+
},
39243928
"You cannot rename this element.": {
39253929
"category": "Error",
39263930
"code": 8000

0 commit comments

Comments
 (0)