Skip to content

Commit c97dfff

Browse files
committed
Support 'this' in inferred method bodies
1 parent fcd00a5 commit c97dfff

3 files changed

Lines changed: 56 additions & 0 deletions

File tree

src/compiler/checker.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6897,6 +6897,23 @@ namespace ts {
68976897
const symbol = getSymbolOfNode(container.parent);
68986898
return container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
68996899
}
6900+
6901+
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
6902+
// of a x.prototype.y = function [name]() { .... }
6903+
if (isInJavaScriptFile(node) && container.kind === SyntaxKind.FunctionExpression) {
6904+
if (getSpecialPropertyAssignmentKind(container.parent) === SpecialPropertyAssignmentKind.PrototypeProperty) {
6905+
// Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container')
6906+
const className = (((container.parent as BinaryExpression) // x.protoype.y = f
6907+
.left as PropertyAccessExpression) // x.prototype.y
6908+
.expression as PropertyAccessExpression) // x.prototype
6909+
.expression; // x
6910+
const classSymbol = checkExpression(className).symbol;
6911+
if (classSymbol.members) {
6912+
return createAnonymousType(undefined, classSymbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
6913+
}
6914+
}
6915+
}
6916+
69006917
return anyType;
69016918
}
69026919

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
///<reference path="fourslash.ts" />
2+
3+
// Inside an inferred method body, the type of 'this' is the class type
4+
5+
// @allowNonTsExtensions: true
6+
// @Filename: myMod.js
7+
//// function myCtor(x) {
8+
//// this.qua = 10;
9+
//// }
10+
//// myCtor.prototype.foo = function() { return this/**/; };
11+
//// myCtor.prototype.bar = function() { return '' };
12+
////
13+
14+
goTo.marker();
15+
edit.insert('.');
16+
17+
// Check members of the function
18+
verify.completionListContains('foo', undefined, undefined, 'property');
19+
verify.completionListContains('bar', undefined, undefined, 'property');
20+
verify.completionListContains('qua', undefined, undefined, 'property');
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
///<reference path="fourslash.ts" />
2+
3+
// No prototype assignments are needed to enable class inference
4+
5+
// @allowNonTsExtensions: true
6+
// @Filename: myMod.js
7+
//// function myCtor() {
8+
//// this.foo = 'hello';
9+
//// this.bar = 10;
10+
//// }
11+
//// let x = new myCtor();
12+
//// x/**/
13+
14+
goTo.marker();
15+
edit.insert('.');
16+
17+
// Check members of the function
18+
verify.completionListContains('foo', undefined, undefined, 'property');
19+
verify.completionListContains('bar', undefined, undefined, 'property');

0 commit comments

Comments
 (0)