@@ -15809,30 +15809,27 @@ namespace ts {
1580915809 }
1581015810
1581115811 function tryGetThisTypeAt(node: Node, container = getThisContainer(node, /*includeArrowFunctions*/ false)): Type | undefined {
15812+ const isInJS = isInJSFile(node);
1581215813 if (isFunctionLike(container) &&
1581315814 (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
1581415815 // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
15815-
1581615816 // If this is a function in a JS file, it might be a class method.
15817- // Check if it's the RHS of a x.prototype.y = function [name]() { .... }
15818- if (container.kind === SyntaxKind.FunctionExpression &&
15819- container.parent.kind === SyntaxKind.BinaryExpression &&
15820- getAssignmentDeclarationKind(container.parent as BinaryExpression) === AssignmentDeclarationKind.PrototypeProperty) {
15821- // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
15822- const className = (((container.parent as BinaryExpression) // x.prototype.y = f
15823- .left as PropertyAccessExpression) // x.prototype.y
15824- .expression as PropertyAccessExpression) // x.prototype
15825- .expression; // x
15817+ const className = getClassNameFromPrototypeMethod(container);
15818+ if (isInJS && className) {
1582615819 const classSymbol = checkExpression(className).symbol;
1582715820 if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
15828- return getFlowTypeOfReference(node, getInferredClassType(classSymbol));
15821+ const classType = getJavascriptClassType(classSymbol);
15822+ if (classType) {
15823+ return getFlowTypeOfReference(node, classType);
15824+ }
1582915825 }
1583015826 }
1583115827 // Check if it's a constructor definition, can be either a variable decl or function decl
1583215828 // i.e.
1583315829 // * /** @constructor */ function [name]() { ... }
1583415830 // * /** @constructor */ var x = function() { ... }
15835- else if ((container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) &&
15831+ else if (isInJS &&
15832+ (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) &&
1583615833 getJSDocClassTag(container)) {
1583715834 const classType = getJavascriptClassType(container.symbol);
1583815835 if (classType) {
@@ -15852,14 +15849,42 @@ namespace ts {
1585215849 return getFlowTypeOfReference(node, type);
1585315850 }
1585415851
15855- if (isInJSFile(node) ) {
15852+ if (isInJS ) {
1585615853 const type = getTypeForThisExpressionFromJSDoc(container);
1585715854 if (type && type !== errorType) {
1585815855 return getFlowTypeOfReference(node, type);
1585915856 }
1586015857 }
1586115858 }
1586215859
15860+ function getClassNameFromPrototypeMethod(container: Node) {
15861+ // Check if it's the RHS of a x.prototype.y = function [name]() { .... }
15862+ if (container.kind === SyntaxKind.FunctionExpression &&
15863+ isBinaryExpression(container.parent) &&
15864+ getAssignmentDeclarationKind(container.parent) === AssignmentDeclarationKind.PrototypeProperty) {
15865+ // Get the 'x' of 'x.prototype.y = container'
15866+ return ((container.parent // x.prototype.y = container
15867+ .left as PropertyAccessExpression) // x.prototype.y
15868+ .expression as PropertyAccessExpression) // x.prototype
15869+ .expression; // x
15870+ }
15871+ // x.prototype = { method() { } }
15872+ else if (container.kind === SyntaxKind.MethodDeclaration &&
15873+ container.parent.kind === SyntaxKind.ObjectLiteralExpression &&
15874+ isBinaryExpression(container.parent.parent) &&
15875+ getAssignmentDeclarationKind(container.parent.parent) === AssignmentDeclarationKind.Prototype) {
15876+ return (container.parent.parent.left as PropertyAccessExpression).expression;
15877+ }
15878+ // x.prototype = { method: function() { } }
15879+ else if (container.kind === SyntaxKind.FunctionExpression &&
15880+ container.parent.kind === SyntaxKind.PropertyAssignment &&
15881+ container.parent.parent.kind === SyntaxKind.ObjectLiteralExpression &&
15882+ isBinaryExpression(container.parent.parent.parent) &&
15883+ getAssignmentDeclarationKind(container.parent.parent.parent) === AssignmentDeclarationKind.Prototype) {
15884+ return (container.parent.parent.parent.left as PropertyAccessExpression).expression;
15885+ }
15886+ }
15887+
1586315888 function getTypeForThisExpressionFromJSDoc(node: Node) {
1586415889 const jsdocType = getJSDocType(node);
1586515890 if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) {
0 commit comments