@@ -8179,6 +8179,21 @@ namespace ts {
81798179 captureLexicalThis(node, container);
81808180 }
81818181 if (isFunctionLike(container)) {
8182+ // If this is a function in a JS file, it might be a class method. Check if it's the RHS
8183+ // of a x.prototype.y = function [name]() { .... }
8184+ if (container.kind === SyntaxKind.FunctionExpression &&
8185+ isInJavaScriptFile(container.parent) &&
8186+ getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
8187+ // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
8188+ const className = (((container.parent as BinaryExpression) // x.prototype.y = f
8189+ .left as PropertyAccessExpression) // x.prototype.y
8190+ .expression as PropertyAccessExpression) // x.prototype
8191+ .expression; // x
8192+ const classSymbol = checkExpression(className).symbol;
8193+ if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
8194+ return getInferredClassType(classSymbol);
8195+ }
8196+ }
81828197 const type = getContextuallyTypedThisType(container);
81838198 if (type) {
81848199 return type;
@@ -8190,9 +8205,13 @@ namespace ts {
81908205 if (container.parent && container.parent.kind === SyntaxKind.ObjectLiteralExpression) {
81918206 // Note: this works because object literal methods are deferred,
81928207 // which means that the type of the containing object literal is already known.
8193- const type = checkExpressionCached(<ObjectLiteralExpression>container.parent);
8194- if (type) {
8195- return type;
8208+ const contextualType = getContextualType(container.parent as ObjectLiteralExpression);
8209+ const literalType = checkExpressionCached(<ObjectLiteralExpression>container.parent);
8210+ if (contextualType && literalType) {
8211+ return getIntersectionType([contextualType, literalType]);
8212+ }
8213+ else if (contextualType || literalType) {
8214+ return contextualType || literalType;
81968215 }
81978216 }
81988217 }
@@ -8207,22 +8226,6 @@ namespace ts {
82078226 if (type && type !== unknownType) {
82088227 return type;
82098228 }
8210-
8211- // If this is a function in a JS file, it might be a class method. Check if it's the RHS
8212- // of a x.prototype.y = function [name]() { .... }
8213- if (container.kind === SyntaxKind.FunctionExpression) {
8214- if (getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
8215- // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
8216- const className = (((container.parent as BinaryExpression) // x.prototype.y = f
8217- .left as PropertyAccessExpression) // x.prototype.y
8218- .expression as PropertyAccessExpression) // x.prototype
8219- .expression; // x
8220- const classSymbol = checkExpression(className).symbol;
8221- if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
8222- return getInferredClassType(classSymbol);
8223- }
8224- }
8225- }
82268229 }
82278230
82288231 if (compilerOptions.noImplicitThis) {
@@ -8450,6 +8453,12 @@ namespace ts {
84508453 if ((isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) &&
84518454 isContextSensitive(func) &&
84528455 func.kind !== SyntaxKind.ArrowFunction) {
8456+ const type = isObjectLiteralMethod(func)
8457+ ? getContextualTypeForObjectLiteralMethod(func)
8458+ : getApparentTypeOfContextualType(func);
8459+ if (type === anyType) {
8460+ return anyType;
8461+ }
84538462 const contextualSignature = getContextualSignature(func);
84548463 if (contextualSignature) {
84558464 return contextualSignature.thisType;
0 commit comments