Skip to content

Commit b49859b

Browse files
authored
Merge pull request microsoft#14510 from Microsoft/fixNullableThisType
Fix nullable 'this' type
2 parents 19b2782 + a4d2c57 commit b49859b

File tree

5 files changed

+771
-240
lines changed

5 files changed

+771
-240
lines changed

src/compiler/checker.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -11601,7 +11601,7 @@ namespace ts {
1160111601
}
1160211602
}
1160311603
}
11604-
if (compilerOptions.noImplicitThis) {
11604+
if (noImplicitThis) {
1160511605
const containingLiteral = getContainingObjectLiteral(func);
1160611606
if (containingLiteral) {
1160711607
// We have an object literal method. Check if the containing object literal has a contextual type
@@ -11622,9 +11622,9 @@ namespace ts {
1162211622
type = getApparentTypeOfContextualType(literal);
1162311623
}
1162411624
// There was no contextual ThisType<T> for the containing object literal, so the contextual type
11625-
// for 'this' is the contextual type for the containing object literal or the type of the object
11626-
// literal itself.
11627-
return contextualType || checkExpressionCached(containingLiteral);
11625+
// for 'this' is the non-null form of the contextual type for the containing object literal or
11626+
// the type of the object literal itself.
11627+
return contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral);
1162811628
}
1162911629
// In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
1163011630
// contextual type for 'this' is 'obj'.

tests/baselines/reference/thisTypeInObjectLiterals2.js

+99
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,42 @@ let p1: Point = {
4747
}
4848
};
4949

50+
let p2: Point | null = {
51+
x: 10,
52+
y: 20,
53+
moveBy(dx, dy, dz) {
54+
this.x += dx;
55+
this.y += dy;
56+
if (this.z && dz) {
57+
this.z += dz;
58+
}
59+
}
60+
};
61+
62+
let p3: Point | undefined = {
63+
x: 10,
64+
y: 20,
65+
moveBy(dx, dy, dz) {
66+
this.x += dx;
67+
this.y += dy;
68+
if (this.z && dz) {
69+
this.z += dz;
70+
}
71+
}
72+
};
73+
74+
let p4: Point | null | undefined = {
75+
x: 10,
76+
y: 20,
77+
moveBy(dx, dy, dz) {
78+
this.x += dx;
79+
this.y += dy;
80+
if (this.z && dz) {
81+
this.z += dz;
82+
}
83+
}
84+
};
85+
5086
declare function f1(p: Point): void;
5187

5288
f1({
@@ -61,6 +97,20 @@ f1({
6197
}
6298
});
6399

100+
declare function f2(p: Point | null | undefined): void;
101+
102+
f2({
103+
x: 10,
104+
y: 20,
105+
moveBy(dx, dy, dz) {
106+
this.x += dx;
107+
this.y += dy;
108+
if (this.z && dz) {
109+
this.z += dz;
110+
}
111+
}
112+
});
113+
64114
// In methods of an object literal with a contextual type that includes some
65115
// ThisType<T>, 'this' is of type T.
66116

@@ -196,6 +246,7 @@ vue.hello;
196246
//// [thisTypeInObjectLiterals2.js]
197247
// In methods of an object literal with no contextual type, 'this' has the type
198248
// of the object literal.
249+
"use strict";
199250
var obj1 = {
200251
a: 1,
201252
f: function () {
@@ -228,6 +279,39 @@ var p1 = {
228279
}
229280
}
230281
};
282+
var p2 = {
283+
x: 10,
284+
y: 20,
285+
moveBy: function (dx, dy, dz) {
286+
this.x += dx;
287+
this.y += dy;
288+
if (this.z && dz) {
289+
this.z += dz;
290+
}
291+
}
292+
};
293+
var p3 = {
294+
x: 10,
295+
y: 20,
296+
moveBy: function (dx, dy, dz) {
297+
this.x += dx;
298+
this.y += dy;
299+
if (this.z && dz) {
300+
this.z += dz;
301+
}
302+
}
303+
};
304+
var p4 = {
305+
x: 10,
306+
y: 20,
307+
moveBy: function (dx, dy, dz) {
308+
this.x += dx;
309+
this.y += dy;
310+
if (this.z && dz) {
311+
this.z += dz;
312+
}
313+
}
314+
};
231315
f1({
232316
x: 10,
233317
y: 20,
@@ -239,6 +323,17 @@ f1({
239323
}
240324
}
241325
});
326+
f2({
327+
x: 10,
328+
y: 20,
329+
moveBy: function (dx, dy, dz) {
330+
this.x += dx;
331+
this.y += dy;
332+
if (this.z && dz) {
333+
this.z += dz;
334+
}
335+
}
336+
});
242337
var x1 = makeObject({
243338
data: { x: 0, y: 0 },
244339
methods: {
@@ -328,7 +423,11 @@ declare type Point = {
328423
moveBy(dx: number, dy: number, dz?: number): void;
329424
};
330425
declare let p1: Point;
426+
declare let p2: Point | null;
427+
declare let p3: Point | undefined;
428+
declare let p4: Point | null | undefined;
331429
declare function f1(p: Point): void;
430+
declare function f2(p: Point | null | undefined): void;
332431
declare type ObjectDescriptor<D, M> = {
333432
data?: D;
334433
methods?: M & ThisType<D & M>;

0 commit comments

Comments
 (0)