Skip to content

Commit 2b46656

Browse files
authored
Merge pull request #9061 from Microsoft/fix-this-resolution-in-parameter-initializers
Fix this resolution in parameter initializers
2 parents a4991b9 + e307295 commit 2b46656

File tree

5 files changed

+198
-1
lines changed

5 files changed

+198
-1
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8416,7 +8416,10 @@ namespace ts {
84168416
if (needToCaptureLexicalThis) {
84178417
captureLexicalThis(node, container);
84188418
}
8419-
if (isFunctionLike(container)) {
8419+
if (isFunctionLike(container) &&
8420+
(!isInParameterInitializerBeforeContainingFunction(node) || getFunctionLikeThisParameter(container))) {
8421+
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
8422+
84208423
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
84218424
// of a x.prototype.y = function [name]() { .... }
84228425
if (container.kind === SyntaxKind.FunctionExpression &&
@@ -18507,6 +18510,14 @@ namespace ts {
1850718510
}
1850818511
}
1850918512

18513+
function getFunctionLikeThisParameter(func: FunctionLikeDeclaration) {
18514+
if (func.parameters.length &&
18515+
func.parameters[0].name.kind === SyntaxKind.Identifier &&
18516+
(<Identifier>func.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
18517+
return func.parameters[0];
18518+
}
18519+
}
18520+
1851018521
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
1851118522
if (isDynamicName(node)) {
1851218523
return grammarErrorOnNode(node, message);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//// [inferParameterWithMethodCallInitializer.ts]
2+
function getNumber(): number {
3+
return 1;
4+
}
5+
class Example {
6+
getNumber(): number {
7+
return 1;
8+
}
9+
doSomething(a = this.getNumber()): typeof a {
10+
return a;
11+
}
12+
}
13+
function weird(this: Example, a = this.getNumber()) {
14+
return a;
15+
}
16+
class Weird {
17+
doSomething(this: Example, a = this.getNumber()) {
18+
return a;
19+
}
20+
}
21+
22+
23+
//// [inferParameterWithMethodCallInitializer.js]
24+
function getNumber() {
25+
return 1;
26+
}
27+
var Example = (function () {
28+
function Example() {
29+
}
30+
Example.prototype.getNumber = function () {
31+
return 1;
32+
};
33+
Example.prototype.doSomething = function (a) {
34+
if (a === void 0) { a = this.getNumber(); }
35+
return a;
36+
};
37+
return Example;
38+
}());
39+
function weird(a) {
40+
if (a === void 0) { a = this.getNumber(); }
41+
return a;
42+
}
43+
var Weird = (function () {
44+
function Weird() {
45+
}
46+
Weird.prototype.doSomething = function (a) {
47+
if (a === void 0) { a = this.getNumber(); }
48+
return a;
49+
};
50+
return Weird;
51+
}());
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
=== tests/cases/compiler/inferParameterWithMethodCallInitializer.ts ===
2+
function getNumber(): number {
3+
>getNumber : Symbol(getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 0, 0))
4+
5+
return 1;
6+
}
7+
class Example {
8+
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
9+
10+
getNumber(): number {
11+
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
12+
13+
return 1;
14+
}
15+
doSomething(a = this.getNumber()): typeof a {
16+
>doSomething : Symbol(Example.doSomething, Decl(inferParameterWithMethodCallInitializer.ts, 6, 5))
17+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 7, 16))
18+
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
19+
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
20+
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
21+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 7, 16))
22+
23+
return a;
24+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 7, 16))
25+
}
26+
}
27+
function weird(this: Example, a = this.getNumber()) {
28+
>weird : Symbol(weird, Decl(inferParameterWithMethodCallInitializer.ts, 10, 1))
29+
>this : Symbol(this, Decl(inferParameterWithMethodCallInitializer.ts, 11, 15))
30+
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
31+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 11, 29))
32+
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
33+
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
34+
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
35+
36+
return a;
37+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 11, 29))
38+
}
39+
class Weird {
40+
>Weird : Symbol(Weird, Decl(inferParameterWithMethodCallInitializer.ts, 13, 1))
41+
42+
doSomething(this: Example, a = this.getNumber()) {
43+
>doSomething : Symbol(Weird.doSomething, Decl(inferParameterWithMethodCallInitializer.ts, 14, 13))
44+
>this : Symbol(this, Decl(inferParameterWithMethodCallInitializer.ts, 15, 16))
45+
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
46+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 15, 30))
47+
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
48+
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
49+
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
50+
51+
return a;
52+
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 15, 30))
53+
}
54+
}
55+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
=== tests/cases/compiler/inferParameterWithMethodCallInitializer.ts ===
2+
function getNumber(): number {
3+
>getNumber : () => number
4+
5+
return 1;
6+
>1 : number
7+
}
8+
class Example {
9+
>Example : Example
10+
11+
getNumber(): number {
12+
>getNumber : () => number
13+
14+
return 1;
15+
>1 : number
16+
}
17+
doSomething(a = this.getNumber()): typeof a {
18+
>doSomething : (a?: number) => number
19+
>a : number
20+
>this.getNumber() : number
21+
>this.getNumber : () => number
22+
>this : this
23+
>getNumber : () => number
24+
>a : number
25+
26+
return a;
27+
>a : number
28+
}
29+
}
30+
function weird(this: Example, a = this.getNumber()) {
31+
>weird : (this: Example, a?: number) => number
32+
>this : Example
33+
>Example : Example
34+
>a : number
35+
>this.getNumber() : number
36+
>this.getNumber : () => number
37+
>this : Example
38+
>getNumber : () => number
39+
40+
return a;
41+
>a : number
42+
}
43+
class Weird {
44+
>Weird : Weird
45+
46+
doSomething(this: Example, a = this.getNumber()) {
47+
>doSomething : (this: Example, a?: number) => number
48+
>this : Example
49+
>Example : Example
50+
>a : number
51+
>this.getNumber() : number
52+
>this.getNumber : () => number
53+
>this : Example
54+
>getNumber : () => number
55+
56+
return a;
57+
>a : number
58+
}
59+
}
60+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @noImplicitAny: true
2+
function getNumber(): number {
3+
return 1;
4+
}
5+
class Example {
6+
getNumber(): number {
7+
return 1;
8+
}
9+
doSomething(a = this.getNumber()): typeof a {
10+
return a;
11+
}
12+
}
13+
function weird(this: Example, a = this.getNumber()) {
14+
return a;
15+
}
16+
class Weird {
17+
doSomething(this: Example, a = this.getNumber()) {
18+
return a;
19+
}
20+
}

0 commit comments

Comments
 (0)