Skip to content

Commit 655e24c

Browse files
committed
Merge pull request #8382 from Microsoft/this-type-for-object-literal-function-properties
Type 'this' in function properties of object literals
2 parents 9120121 + 755ba73 commit 655e24c

21 files changed

+171
-98
lines changed

Diff for: src/compiler/checker.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8206,10 +8206,11 @@ namespace ts {
82068206
if (signature.thisType) {
82078207
return signature.thisType;
82088208
}
8209-
if (container.parent && container.parent.kind === SyntaxKind.ObjectLiteralExpression) {
8209+
const parentObject = container.parent && container.parent.kind === SyntaxKind.PropertyAssignment ? container.parent.parent : container.parent;
8210+
if (parentObject && parentObject.kind === SyntaxKind.ObjectLiteralExpression) {
82108211
// Note: this works because object literal methods are deferred,
82118212
// which means that the type of the containing object literal is already known.
8212-
const type = checkExpressionCached(<ObjectLiteralExpression>container.parent);
8213+
const type = checkExpressionCached(<ObjectLiteralExpression>parentObject);
82138214
if (type) {
82148215
return type;
82158216
}

Diff for: tests/baselines/reference/commentsOnObjectLiteral2.errors.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
tests/cases/compiler/commentsOnObjectLiteral2.ts(1,14): error TS2304: Cannot find name 'makeClass'.
2+
tests/cases/compiler/commentsOnObjectLiteral2.ts(9,17): error TS2339: Property 'name' does not exist on type '{ initialize: (name: any) => void; }'.
23

34

4-
==== tests/cases/compiler/commentsOnObjectLiteral2.ts (1 errors) ====
5+
==== tests/cases/compiler/commentsOnObjectLiteral2.ts (2 errors) ====
56
var Person = makeClass(
67
~~~~~~~~~
78
!!! error TS2304: Cannot find name 'makeClass'.
@@ -13,6 +14,8 @@ tests/cases/compiler/commentsOnObjectLiteral2.ts(1,14): error TS2304: Cannot fin
1314
*/
1415
initialize: function(name) {
1516
this.name = name;
17+
~~~~
18+
!!! error TS2339: Property 'name' does not exist on type '{ initialize: (name: any) => void; }'.
1619
} /* trailing comment 1*/,
1720
}
1821
);

Diff for: tests/baselines/reference/fatarrowfunctions.symbols

+5
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ var messenger = {
163163

164164
setTimeout(() => { this.message.toString(); }, 3000);
165165
>setTimeout : Symbol(setTimeout, Decl(fatarrowfunctions.ts, 34, 1))
166+
>this.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --))
167+
>this.message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17))
168+
>this : Symbol(, Decl(fatarrowfunctions.ts, 38, 15))
169+
>message : Symbol(message, Decl(fatarrowfunctions.ts, 38, 17))
170+
>toString : Symbol(String.toString, Decl(lib.d.ts, --, --))
166171
}
167172
};
168173

Diff for: tests/baselines/reference/fatarrowfunctions.types

+6-6
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,12 @@ var messenger = {
234234
>setTimeout(() => { this.message.toString(); }, 3000) : number
235235
>setTimeout : (expression: any, msec?: number, language?: any) => number
236236
>() => { this.message.toString(); } : () => void
237-
>this.message.toString() : any
238-
>this.message.toString : any
239-
>this.message : any
240-
>this : any
241-
>message : any
242-
>toString : any
237+
>this.message.toString() : string
238+
>this.message.toString : () => string
239+
>this.message : string
240+
>this : { message: string; start: () => void; }
241+
>message : string
242+
>toString : () => string
243243
>3000 : number
244244
}
245245
};

Diff for: tests/baselines/reference/fatarrowfunctionsInFunctions.symbols

+5
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@ var messenger = {
1616

1717
var _self = this;
1818
>_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11))
19+
>this : Symbol(, Decl(fatarrowfunctionsInFunctions.ts, 2, 15))
1920

2021
setTimeout(function() {
2122
>setTimeout : Symbol(setTimeout, Decl(fatarrowfunctionsInFunctions.ts, 0, 0))
2223

2324
_self.message.toString();
25+
>_self.message.toString : Symbol(String.toString, Decl(lib.d.ts, --, --))
26+
>_self.message : Symbol(message, Decl(fatarrowfunctionsInFunctions.ts, 2, 17))
2427
>_self : Symbol(_self, Decl(fatarrowfunctionsInFunctions.ts, 5, 11))
28+
>message : Symbol(message, Decl(fatarrowfunctionsInFunctions.ts, 2, 17))
29+
>toString : Symbol(String.toString, Decl(lib.d.ts, --, --))
2530

2631
}, 3000);
2732
}

Diff for: tests/baselines/reference/fatarrowfunctionsInFunctions.types

+8-8
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,21 @@ var messenger = {
1818
>function() { var _self = this; setTimeout(function() { _self.message.toString(); }, 3000); } : () => void
1919

2020
var _self = this;
21-
>_self : any
22-
>this : any
21+
>_self : { message: string; start: () => void; }
22+
>this : { message: string; start: () => void; }
2323

2424
setTimeout(function() {
2525
>setTimeout(function() { _self.message.toString(); }, 3000) : number
2626
>setTimeout : (expression: any, msec?: number, language?: any) => number
2727
>function() { _self.message.toString(); } : () => void
2828

2929
_self.message.toString();
30-
>_self.message.toString() : any
31-
>_self.message.toString : any
32-
>_self.message : any
33-
>_self : any
34-
>message : any
35-
>toString : any
30+
>_self.message.toString() : string
31+
>_self.message.toString : () => string
32+
>_self.message : string
33+
>_self : { message: string; start: () => void; }
34+
>message : string
35+
>toString : () => string
3636

3737
}, 3000);
3838
>3000 : number

Diff for: tests/baselines/reference/looseThisTypeInFunctions.errors.txt

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(21,1): error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'.
22
The 'this' types of each signature are incompatible.
33
Type 'void' is not assignable to type 'C'.
4+
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(25,27): error TS2339: Property 'length' does not exist on type 'number'.
45
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(33,28): error TS2339: Property 'length' does not exist on type 'number'.
56
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(37,9): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'I'.
67
tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error TS2339: Property 'length' does not exist on type 'number'.
78

89

9-
==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (4 errors) ====
10+
==== tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts (5 errors) ====
1011
interface I {
1112
n: number;
1213
explicitThis(this: this, m: number): number;
@@ -32,12 +33,14 @@ tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error
3233
!!! error TS2322: Type '(this: C, m: number) => number' is not assignable to type '(this: void, m: number) => number'.
3334
!!! error TS2322: The 'this' types of each signature are incompatible.
3435
!!! error TS2322: Type 'void' is not assignable to type 'C'.
35-
let o = {
36+
let o = {
3637
n: 101,
37-
explicitThis: function (m: number) {
38-
return m + this.n.length; // ok, this.n: any
38+
explicitThis: function (m: number) {
39+
return m + this.n.length; // error, 'length' does not exist on 'number'
40+
~~~~~~
41+
!!! error TS2339: Property 'length' does not exist on type 'number'.
3942
},
40-
implicitThis(m: number): number { return m; }
43+
implicitThis(m: number): number { return m; }
4144
};
4245
let i: I = o;
4346
let o2: I = {
@@ -63,4 +66,5 @@ tests/cases/conformance/types/thisType/looseThisTypeInFunctions.ts(46,20): error
6366
return this.n.length; // error, this.n: number
6467
~~~~~~
6568
!!! error TS2339: Property 'length' does not exist on type 'number'.
66-
}
69+
}
70+

Diff for: tests/baselines/reference/looseThisTypeInFunctions.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ class C implements I {
2020
}
2121
let c = new C();
2222
c.explicitVoid = c.explicitThis; // error, 'void' is missing everything
23-
let o = {
23+
let o = {
2424
n: 101,
25-
explicitThis: function (m: number) {
26-
return m + this.n.length; // ok, this.n: any
25+
explicitThis: function (m: number) {
26+
return m + this.n.length; // error, 'length' does not exist on 'number'
2727
},
28-
implicitThis(m: number): number { return m; }
28+
implicitThis(m: number): number { return m; }
2929
};
3030
let i: I = o;
3131
let o2: I = {
@@ -45,7 +45,8 @@ o.implicitThis = c.explicitThis; // ok, implicitThis(this:any) is assignable to
4545
o.implicitThis = i.explicitThis;
4646
i.explicitThis = function(m) {
4747
return this.n.length; // error, this.n: number
48-
}
48+
}
49+
4950

5051
//// [looseThisTypeInFunctions.js]
5152
var C = (function () {
@@ -67,7 +68,7 @@ c.explicitVoid = c.explicitThis; // error, 'void' is missing everything
6768
var o = {
6869
n: 101,
6970
explicitThis: function (m) {
70-
return m + this.n.length; // ok, this.n: any
71+
return m + this.n.length; // error, 'length' does not exist on 'number'
7172
},
7273
implicitThis: function (m) { return m; }
7374
};

Diff for: tests/baselines/reference/selfInLambdas.symbols

+7
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,15 @@ var o = {
3737
>onmousemove : Symbol(Window.onmousemove, Decl(selfInLambdas.ts, 6, 18))
3838

3939
this.counter++
40+
>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9))
41+
>this : Symbol(, Decl(selfInLambdas.ts, 10, 7))
42+
>counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9))
43+
4044
var f = () => this.counter;
4145
>f : Symbol(f, Decl(selfInLambdas.ts, 18, 15))
46+
>this.counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9))
47+
>this : Symbol(, Decl(selfInLambdas.ts, 10, 7))
48+
>counter : Symbol(counter, Decl(selfInLambdas.ts, 10, 9))
4249

4350
}
4451

Diff for: tests/baselines/reference/selfInLambdas.types

+8-8
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ var o = {
4343

4444
this.counter++
4545
>this.counter++ : number
46-
>this.counter : any
47-
>this : any
48-
>counter : any
46+
>this.counter : number
47+
>this : { counter: number; start: () => void; }
48+
>counter : number
4949

5050
var f = () => this.counter;
51-
>f : () => any
52-
>() => this.counter : () => any
53-
>this.counter : any
54-
>this : any
55-
>counter : any
51+
>f : () => number
52+
>() => this.counter : () => number
53+
>this.counter : number
54+
>this : { counter: number; start: () => void; }
55+
>counter : number
5656

5757
}
5858

Diff for: tests/baselines/reference/thisBinding2.symbols

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ var messenger = {
5050
return setTimeout(() => { var x = this.message; }, 3000);
5151
>setTimeout : Symbol(setTimeout, Decl(thisBinding2.ts, 12, 1))
5252
>x : Symbol(x, Decl(thisBinding2.ts, 17, 37))
53+
>this.message : Symbol(message, Decl(thisBinding2.ts, 14, 17))
54+
>this : Symbol(, Decl(thisBinding2.ts, 14, 15))
55+
>message : Symbol(message, Decl(thisBinding2.ts, 14, 17))
5356
}
5457
};
5558

Diff for: tests/baselines/reference/thisBinding2.types

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ var messenger = {
6767
>setTimeout(() => { var x = this.message; }, 3000) : number
6868
>setTimeout : (expression: any, msec?: number, language?: any) => number
6969
>() => { var x = this.message; } : () => void
70-
>x : any
71-
>this.message : any
72-
>this : any
73-
>message : any
70+
>x : string
71+
>this.message : string
72+
>this : { message: string; start: () => number; }
73+
>message : string
7474
>3000 : number
7575
}
7676
};

Diff for: tests/baselines/reference/thisInPropertyBoundDeclarations.symbols

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class A {
7070

7171
a: function() { return this; },
7272
>a : Symbol(a, Decl(thisInPropertyBoundDeclarations.ts, 33, 13))
73+
>this : Symbol(, Decl(thisInPropertyBoundDeclarations.ts, 33, 11))
7374

7475
};
7576

@@ -79,6 +80,7 @@ class A {
7980
return {
8081
a: function() { return this; },
8182
>a : Symbol(a, Decl(thisInPropertyBoundDeclarations.ts, 38, 16))
83+
>this : Symbol(, Decl(thisInPropertyBoundDeclarations.ts, 38, 14))
8284

8385
};
8486
};

Diff for: tests/baselines/reference/thisInPropertyBoundDeclarations.types

+6-6
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ class A {
8484
>{ a: function() { return this; }, } : { a: () => any; }
8585

8686
a: function() { return this; },
87-
>a : () => any
88-
>function() { return this; } : () => any
89-
>this : any
87+
>a : () => { a: any; }
88+
>function() { return this; } : () => { a: any; }
89+
>this : { a: () => any; }
9090

9191
};
9292

@@ -98,9 +98,9 @@ class A {
9898
>{ a: function() { return this; }, } : { a: () => any; }
9999

100100
a: function() { return this; },
101-
>a : () => any
102-
>function() { return this; } : () => any
103-
>this : any
101+
>a : () => { a: any; }
102+
>function() { return this; } : () => { a: any; }
103+
>this : { a: () => any; }
104104

105105
};
106106
};

Diff for: tests/baselines/reference/thisTypeInObjectLiterals.js

+7
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ let o = {
33
d: "bar",
44
m() {
55
return this.d.length;
6+
},
7+
f: function() {
8+
return this.d.length;
69
}
710
}
11+
812
let mutuallyRecursive = {
913
a: 100,
1014
start() {
@@ -35,6 +39,9 @@ var o = {
3539
d: "bar",
3640
m: function () {
3741
return this.d.length;
42+
},
43+
f: function () {
44+
return this.d.length;
3845
}
3946
};
4047
var mutuallyRecursive = {

0 commit comments

Comments
 (0)