Skip to content

Commit 8b81d19

Browse files
authored
Enable CFA on this keyword unconditionally (#21490)
1 parent 06c5d39 commit 8b81d19

5 files changed

+115
-3
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13341,13 +13341,13 @@ namespace ts {
1334113341
.expression; // x
1334213342
const classSymbol = checkExpression(className).symbol;
1334313343
if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
13344-
return getInferredClassType(classSymbol);
13344+
return getFlowTypeOfReference(node, getInferredClassType(classSymbol));
1334513345
}
1334613346
}
1334713347

1334813348
const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
1334913349
if (thisType) {
13350-
return thisType;
13350+
return getFlowTypeOfReference(node, thisType);
1335113351
}
1335213352
}
1335313353

@@ -13360,7 +13360,7 @@ namespace ts {
1336013360
if (isInJavaScriptFile(node)) {
1336113361
const type = getTypeForThisExpressionFromJSDoc(container);
1336213362
if (type && type !== unknownType) {
13363-
return type;
13363+
return getFlowTypeOfReference(node, type);
1336413364
}
1336513365
}
1336613366
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [controlFlowAnalysisOnBareThisKeyword.ts]
2+
declare function isBig(x: any): x is { big: true };
3+
function bigger(this: {}) {
4+
if (isBig(this)) {
5+
this.big; // Expect property to exist
6+
}
7+
}
8+
9+
function bar(this: string | number) {
10+
if (typeof this === "string") {
11+
const x: string = this;
12+
}
13+
}
14+
15+
//// [controlFlowAnalysisOnBareThisKeyword.js]
16+
"use strict";
17+
function bigger() {
18+
if (isBig(this)) {
19+
this.big; // Expect property to exist
20+
}
21+
}
22+
function bar() {
23+
if (typeof this === "string") {
24+
var x = this;
25+
}
26+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts ===
2+
declare function isBig(x: any): x is { big: true };
3+
>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0))
4+
>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23))
5+
>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 23))
6+
>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38))
7+
8+
function bigger(this: {}) {
9+
>bigger : Symbol(bigger, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 51))
10+
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16))
11+
12+
if (isBig(this)) {
13+
>isBig : Symbol(isBig, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 0))
14+
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16))
15+
16+
this.big; // Expect property to exist
17+
>this.big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38))
18+
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 1, 16))
19+
>big : Symbol(big, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 0, 38))
20+
}
21+
}
22+
23+
function bar(this: string | number) {
24+
>bar : Symbol(bar, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 5, 1))
25+
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13))
26+
27+
if (typeof this === "string") {
28+
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13))
29+
30+
const x: string = this;
31+
>x : Symbol(x, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 9, 13))
32+
>this : Symbol(this, Decl(controlFlowAnalysisOnBareThisKeyword.ts, 7, 13))
33+
}
34+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
=== tests/cases/compiler/controlFlowAnalysisOnBareThisKeyword.ts ===
2+
declare function isBig(x: any): x is { big: true };
3+
>isBig : (x: any) => x is { big: true; }
4+
>x : any
5+
>x : any
6+
>big : true
7+
>true : true
8+
9+
function bigger(this: {}) {
10+
>bigger : (this: {}) => void
11+
>this : {}
12+
13+
if (isBig(this)) {
14+
>isBig(this) : boolean
15+
>isBig : (x: any) => x is { big: true; }
16+
>this : {}
17+
18+
this.big; // Expect property to exist
19+
>this.big : true
20+
>this : { big: true; }
21+
>big : true
22+
}
23+
}
24+
25+
function bar(this: string | number) {
26+
>bar : (this: string | number) => void
27+
>this : string | number
28+
29+
if (typeof this === "string") {
30+
>typeof this === "string" : boolean
31+
>typeof this : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
32+
>this : string | number
33+
>"string" : "string"
34+
35+
const x: string = this;
36+
>x : string
37+
>this : string
38+
}
39+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @strict: true
2+
declare function isBig(x: any): x is { big: true };
3+
function bigger(this: {}) {
4+
if (isBig(this)) {
5+
this.big; // Expect property to exist
6+
}
7+
}
8+
9+
function bar(this: string | number) {
10+
if (typeof this === "string") {
11+
const x: string = this;
12+
}
13+
}

0 commit comments

Comments
 (0)