@@ -295,6 +295,15 @@ namespace ts {
295295 getAccessibleSymbolChain,
296296 getTypePredicateOfSignature,
297297 resolveExternalModuleSymbol,
298+ tryGetThisTypeAt: node => {
299+ node = getParseTreeNode(node);
300+ return node && tryGetThisTypeAt(node, /*isForTest*/ true);
301+ },
302+ isMemberSymbol: symbol =>
303+ symbol.flags & SymbolFlags.ClassMember
304+ && symbol !== argumentsSymbol
305+ && symbol !== undefinedSymbol
306+ && !(symbol.parent && symbol.parent.flags & SymbolFlags.Module),
298307 };
299308
300309 const tupleTypes: GenericType[] = [];
@@ -13221,13 +13230,24 @@ namespace ts {
1322113230 }
1322213231
1322313232 function checkThisExpression(node: Node): Type {
13233+ const type = tryGetThisTypeAt(node, /*isForTest*/ false);
13234+ if (type) return type;
13235+
13236+ if (noImplicitThis) {
13237+ // With noImplicitThis, functions may not reference 'this' if it has type 'any'
13238+ error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
13239+ }
13240+ return anyType;
13241+ }
13242+
13243+ function tryGetThisTypeAt(node: Node, isForTest: boolean): Type | undefined {
1322413244 // Stop at the first arrow function so that we can
1322513245 // tell whether 'this' needs to be captured.
1322613246 let container = getThisContainer(node, /* includeArrowFunctions */ true);
1322713247 let needToCaptureLexicalThis = false;
1322813248
1322913249 if (container.kind === SyntaxKind.Constructor) {
13230- checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
13250+ if (!isForTest) checkThisBeforeSuper(node, container, Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
1323113251 }
1323213252
1323313253 // Now skip arrow functions to get the "real" owner of 'this'.
@@ -13238,36 +13258,14 @@ namespace ts {
1323813258 needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES2015);
1323913259 }
1324013260
13241- switch (container.kind) {
13242- case SyntaxKind.ModuleDeclaration:
13243- error(node, Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
13244- // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13245- break;
13246- case SyntaxKind.EnumDeclaration:
13247- error(node, Diagnostics.this_cannot_be_referenced_in_current_location);
13248- // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13249- break;
13250- case SyntaxKind.Constructor:
13251- if (isInConstructorArgumentInitializer(node, container)) {
13252- error(node, Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
13253- // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13254- }
13255- break;
13256- case SyntaxKind.PropertyDeclaration:
13257- case SyntaxKind.PropertySignature:
13258- if (hasModifier(container, ModifierFlags.Static)) {
13259- error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
13260- // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13261- }
13262- break;
13263- case SyntaxKind.ComputedPropertyName:
13264- error(node, Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
13265- break;
13266- }
13261+ if (!isForTest) {
13262+ reportErrorsForThisExpression(node, container);
1326713263
13268- if (needToCaptureLexicalThis) {
13269- captureLexicalThis(node, container);
13264+ if (needToCaptureLexicalThis) {
13265+ captureLexicalThis(node, container);
13266+ }
1327013267 }
13268+
1327113269 if (isFunctionLike(container) &&
1327213270 (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
1327313271 // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
@@ -13306,12 +13304,35 @@ namespace ts {
1330613304 return type;
1330713305 }
1330813306 }
13307+ }
1330913308
13310- if (noImplicitThis) {
13311- // With noImplicitThis, functions may not reference 'this' if it has type 'any'
13312- error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
13309+ function reportErrorsForThisExpression(node: Node, container: Node): void {
13310+ switch (container.kind) {
13311+ case SyntaxKind.ModuleDeclaration:
13312+ error(node, Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
13313+ // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13314+ break;
13315+ case SyntaxKind.EnumDeclaration:
13316+ error(node, Diagnostics.this_cannot_be_referenced_in_current_location);
13317+ // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13318+ break;
13319+ case SyntaxKind.Constructor:
13320+ if (isInConstructorArgumentInitializer(node, container)) {
13321+ error(node, Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
13322+ // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13323+ }
13324+ break;
13325+ case SyntaxKind.PropertyDeclaration:
13326+ case SyntaxKind.PropertySignature:
13327+ if (hasModifier(container, ModifierFlags.Static)) {
13328+ error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
13329+ // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
13330+ }
13331+ break;
13332+ case SyntaxKind.ComputedPropertyName:
13333+ error(node, Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
13334+ break;
1331313335 }
13314- return anyType;
1331513336 }
1331613337
1331713338 function getTypeForThisExpressionFromJSDoc(node: Node) {
0 commit comments