@@ -15809,30 +15809,27 @@ namespace ts {
15809
15809
}
15810
15810
15811
15811
function tryGetThisTypeAt(node: Node, container = getThisContainer(node, /*includeArrowFunctions*/ false)): Type | undefined {
15812
+ const isInJS = isInJSFile(node);
15812
15813
if (isFunctionLike(container) &&
15813
15814
(!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
15814
15815
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
15815
-
15816
15816
// 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) {
15826
15819
const classSymbol = checkExpression(className).symbol;
15827
15820
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
+ }
15829
15825
}
15830
15826
}
15831
15827
// Check if it's a constructor definition, can be either a variable decl or function decl
15832
15828
// i.e.
15833
15829
// * /** @constructor */ function [name]() { ... }
15834
15830
// * /** @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) &&
15836
15833
getJSDocClassTag(container)) {
15837
15834
const classType = getJavascriptClassType(container.symbol);
15838
15835
if (classType) {
@@ -15852,14 +15849,42 @@ namespace ts {
15852
15849
return getFlowTypeOfReference(node, type);
15853
15850
}
15854
15851
15855
- if (isInJSFile(node) ) {
15852
+ if (isInJS ) {
15856
15853
const type = getTypeForThisExpressionFromJSDoc(container);
15857
15854
if (type && type !== errorType) {
15858
15855
return getFlowTypeOfReference(node, type);
15859
15856
}
15860
15857
}
15861
15858
}
15862
15859
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
+
15863
15888
function getTypeForThisExpressionFromJSDoc(node: Node) {
15864
15889
const jsdocType = getJSDocType(node);
15865
15890
if (jsdocType && jsdocType.kind === SyntaxKind.JSDocFunctionType) {
0 commit comments