Support 'this' in inferred method bodies

This commit is contained in:
Ryan Cavanaugh
2015-12-07 11:55:30 -08:00
parent fcd00a59d2
commit c97dffff3b
3 changed files with 56 additions and 0 deletions

View File

@@ -6897,6 +6897,23 @@ namespace ts {
const symbol = getSymbolOfNode(container.parent);
return container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
}
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
// of a x.prototype.y = function [name]() { .... }
if (isInJavaScriptFile(node) && container.kind === SyntaxKind.FunctionExpression) {
if (getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
// Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
const className = (((container.parent as BinaryExpression) // x.protoype.y = f
.left as PropertyAccessExpression) // x.prototype.y
.expression as PropertyAccessExpression) // x.prototype
.expression; // x
const classSymbol = checkExpression(className).symbol;
if (classSymbol.members) {
return createAnonymousType(undefined, classSymbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
}
}
}
return anyType;
}

View File

@@ -0,0 +1,20 @@
///<reference path="fourslash.ts" />
// Inside an inferred method body, the type of 'this' is the class type
// @allowNonTsExtensions: true
// @Filename: myMod.js
//// function myCtor(x) {
//// this.qua = 10;
//// }
//// myCtor.prototype.foo = function() { return this/**/; };
//// myCtor.prototype.bar = function() { return '' };
////
goTo.marker();
edit.insert('.');
// Check members of the function
verify.completionListContains('foo', undefined, undefined, 'property');
verify.completionListContains('bar', undefined, undefined, 'property');
verify.completionListContains('qua', undefined, undefined, 'property');

View File

@@ -0,0 +1,19 @@
///<reference path="fourslash.ts" />
// No prototype assignments are needed to enable class inference
// @allowNonTsExtensions: true
// @Filename: myMod.js
//// function myCtor() {
//// this.foo = 'hello';
//// this.bar = 10;
//// }
//// let x = new myCtor();
//// x/**/
goTo.marker();
edit.insert('.');
// Check members of the function
verify.completionListContains('foo', undefined, undefined, 'property');
verify.completionListContains('bar', undefined, undefined, 'property');