Skip to content

Commit f4c2a22

Browse files
authored
fix flow type of this inside arrow function (#54236)
1 parent bb74c60 commit f4c2a22

File tree

5 files changed

+141
-1
lines changed

5 files changed

+141
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26572,7 +26572,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2657226572
if (container && container !== flowContainer &&
2657326573
reference.kind !== SyntaxKind.PropertyAccessExpression &&
2657426574
reference.kind !== SyntaxKind.ElementAccessExpression &&
26575-
reference.kind !== SyntaxKind.ThisKeyword) {
26575+
!(reference.kind === SyntaxKind.ThisKeyword && container.kind !== SyntaxKind.ArrowFunction)
26576+
) {
2657626577
flow = container.flowNode!;
2657726578
continue;
2657826579
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [thisTypeInFunctions4.ts]
2+
type WrongObject = {value: number};
3+
type CorrectObject = {name: string};
4+
5+
declare function isCorrect(obj: any): obj is CorrectObject
6+
7+
declare function callsCallback(cb: (name: string)=>void)
8+
9+
function problemFunction(this: CorrectObject | WrongObject): void {
10+
//check type
11+
if (!isCorrect(this)) return;
12+
13+
callsCallback((name)=>{
14+
this.name = name; //should not error
15+
type T = typeof this;
16+
});
17+
}
18+
19+
//// [thisTypeInFunctions4.js]
20+
function problemFunction() {
21+
var _this = this;
22+
//check type
23+
if (!isCorrect(this))
24+
return;
25+
callsCallback(function (name) {
26+
_this.name = name; //should not error
27+
});
28+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
=== tests/cases/conformance/types/thisType/thisTypeInFunctions4.ts ===
2+
type WrongObject = {value: number};
3+
>WrongObject : Symbol(WrongObject, Decl(thisTypeInFunctions4.ts, 0, 0))
4+
>value : Symbol(value, Decl(thisTypeInFunctions4.ts, 0, 20))
5+
6+
type CorrectObject = {name: string};
7+
>CorrectObject : Symbol(CorrectObject, Decl(thisTypeInFunctions4.ts, 0, 35))
8+
>name : Symbol(name, Decl(thisTypeInFunctions4.ts, 1, 22))
9+
10+
declare function isCorrect(obj: any): obj is CorrectObject
11+
>isCorrect : Symbol(isCorrect, Decl(thisTypeInFunctions4.ts, 1, 36))
12+
>obj : Symbol(obj, Decl(thisTypeInFunctions4.ts, 3, 27))
13+
>obj : Symbol(obj, Decl(thisTypeInFunctions4.ts, 3, 27))
14+
>CorrectObject : Symbol(CorrectObject, Decl(thisTypeInFunctions4.ts, 0, 35))
15+
16+
declare function callsCallback(cb: (name: string)=>void)
17+
>callsCallback : Symbol(callsCallback, Decl(thisTypeInFunctions4.ts, 3, 58))
18+
>cb : Symbol(cb, Decl(thisTypeInFunctions4.ts, 5, 31))
19+
>name : Symbol(name, Decl(thisTypeInFunctions4.ts, 5, 36))
20+
21+
function problemFunction(this: CorrectObject | WrongObject): void {
22+
>problemFunction : Symbol(problemFunction, Decl(thisTypeInFunctions4.ts, 5, 56))
23+
>this : Symbol(this, Decl(thisTypeInFunctions4.ts, 7, 25))
24+
>CorrectObject : Symbol(CorrectObject, Decl(thisTypeInFunctions4.ts, 0, 35))
25+
>WrongObject : Symbol(WrongObject, Decl(thisTypeInFunctions4.ts, 0, 0))
26+
27+
//check type
28+
if (!isCorrect(this)) return;
29+
>isCorrect : Symbol(isCorrect, Decl(thisTypeInFunctions4.ts, 1, 36))
30+
>this : Symbol(this, Decl(thisTypeInFunctions4.ts, 7, 25))
31+
32+
callsCallback((name)=>{
33+
>callsCallback : Symbol(callsCallback, Decl(thisTypeInFunctions4.ts, 3, 58))
34+
>name : Symbol(name, Decl(thisTypeInFunctions4.ts, 11, 19))
35+
36+
this.name = name; //should not error
37+
>this.name : Symbol(name, Decl(thisTypeInFunctions4.ts, 1, 22))
38+
>this : Symbol(this, Decl(thisTypeInFunctions4.ts, 7, 25))
39+
>name : Symbol(name, Decl(thisTypeInFunctions4.ts, 1, 22))
40+
>name : Symbol(name, Decl(thisTypeInFunctions4.ts, 11, 19))
41+
42+
type T = typeof this;
43+
>T : Symbol(T, Decl(thisTypeInFunctions4.ts, 12, 25))
44+
>this : Symbol(this, Decl(thisTypeInFunctions4.ts, 7, 25))
45+
46+
});
47+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
=== tests/cases/conformance/types/thisType/thisTypeInFunctions4.ts ===
2+
type WrongObject = {value: number};
3+
>WrongObject : { value: number; }
4+
>value : number
5+
6+
type CorrectObject = {name: string};
7+
>CorrectObject : { name: string; }
8+
>name : string
9+
10+
declare function isCorrect(obj: any): obj is CorrectObject
11+
>isCorrect : (obj: any) => obj is CorrectObject
12+
>obj : any
13+
14+
declare function callsCallback(cb: (name: string)=>void)
15+
>callsCallback : (cb: (name: string) => void) => any
16+
>cb : (name: string) => void
17+
>name : string
18+
19+
function problemFunction(this: CorrectObject | WrongObject): void {
20+
>problemFunction : (this: CorrectObject | WrongObject) => void
21+
>this : WrongObject | CorrectObject
22+
23+
//check type
24+
if (!isCorrect(this)) return;
25+
>!isCorrect(this) : boolean
26+
>isCorrect(this) : boolean
27+
>isCorrect : (obj: any) => obj is CorrectObject
28+
>this : WrongObject | CorrectObject
29+
30+
callsCallback((name)=>{
31+
>callsCallback((name)=>{ this.name = name; //should not error type T = typeof this; }) : any
32+
>callsCallback : (cb: (name: string) => void) => any
33+
>(name)=>{ this.name = name; //should not error type T = typeof this; } : (name: string) => void
34+
>name : string
35+
36+
this.name = name; //should not error
37+
>this.name = name : string
38+
>this.name : string
39+
>this : CorrectObject
40+
>name : string
41+
>name : string
42+
43+
type T = typeof this;
44+
>T : CorrectObject
45+
>this : CorrectObject
46+
47+
});
48+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type WrongObject = {value: number};
2+
type CorrectObject = {name: string};
3+
4+
declare function isCorrect(obj: any): obj is CorrectObject
5+
6+
declare function callsCallback(cb: (name: string)=>void)
7+
8+
function problemFunction(this: CorrectObject | WrongObject): void {
9+
//check type
10+
if (!isCorrect(this)) return;
11+
12+
callsCallback((name)=>{
13+
this.name = name; //should not error
14+
type T = typeof this;
15+
});
16+
}

0 commit comments

Comments
 (0)