diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1af122e4e3b4e..d9d2e069e76d9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22471,8 +22471,11 @@ namespace ts { function getFlowCacheKey(node: Node, declaredType: Type, initialType: Type, flowContainer: Node | undefined): string | undefined { switch (node.kind) { case SyntaxKind.Identifier: - const symbol = getResolvedSymbol(node as Identifier); - return symbol !== unknownSymbol ? `${flowContainer ? getNodeId(flowContainer) : "-1"}|${getTypeId(declaredType)}|${getTypeId(initialType)}|${getSymbolId(symbol)}` : undefined; + if (!isThisInTypeQuery(node)) { + const symbol = getResolvedSymbol(node as Identifier); + return symbol !== unknownSymbol ? `${flowContainer ? getNodeId(flowContainer) : "-1"}|${getTypeId(declaredType)}|${getTypeId(initialType)}|${getSymbolId(symbol)}` : undefined; + } + // falls through case SyntaxKind.ThisKeyword: return `0|${flowContainer ? getNodeId(flowContainer) : "-1"}|${getTypeId(declaredType)}|${getTypeId(initialType)}`; case SyntaxKind.NonNullExpression: diff --git a/tests/baselines/reference/typeofThis.errors.txt b/tests/baselines/reference/typeofThis.errors.txt index 0859ccaa2d7c0..a4a3be693aa93 100644 --- a/tests/baselines/reference/typeofThis.errors.txt +++ b/tests/baselines/reference/typeofThis.errors.txt @@ -146,4 +146,25 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts(57,24): let y: string = o.this.x; // should narrow to string } } + } + + class Tests12 { + test1() { // OK + type Test = typeof this; + } + + test2() { // OK + for (;;) {} + type Test = typeof this; + } + + test3() { // expected no compile errors + for (const dummy in []) {} + type Test = typeof this; + } + + test4() { // expected no compile errors + for (const dummy of []) {} + type Test = typeof this; + } } \ No newline at end of file diff --git a/tests/baselines/reference/typeofThis.js b/tests/baselines/reference/typeofThis.js index e06e3e383f405..4de9aac427167 100644 --- a/tests/baselines/reference/typeofThis.js +++ b/tests/baselines/reference/typeofThis.js @@ -120,6 +120,27 @@ class Test11 { let y: string = o.this.x; // should narrow to string } } +} + +class Tests12 { + test1() { // OK + type Test = typeof this; + } + + test2() { // OK + for (;;) {} + type Test = typeof this; + } + + test3() { // expected no compile errors + for (const dummy in []) {} + type Test = typeof this; + } + + test4() { // expected no compile errors + for (const dummy of []) {} + type Test = typeof this; + } } //// [typeofThis.js] @@ -241,3 +262,21 @@ var Test11 = /** @class */ (function () { }; return Test11; }()); +var Tests12 = /** @class */ (function () { + function Tests12() { + } + Tests12.prototype.test1 = function () { + }; + Tests12.prototype.test2 = function () { + for (;;) { } + }; + Tests12.prototype.test3 = function () { + for (var dummy in []) { } + }; + Tests12.prototype.test4 = function () { + for (var _i = 0, _a = []; _i < _a.length; _i++) { + var dummy = _a[_i]; + } + }; + return Tests12; +}()); diff --git a/tests/baselines/reference/typeofThis.symbols b/tests/baselines/reference/typeofThis.symbols index dde439e3d0d96..5314551f51a83 100644 --- a/tests/baselines/reference/typeofThis.symbols +++ b/tests/baselines/reference/typeofThis.symbols @@ -312,3 +312,42 @@ class Test11 { } } } + +class Tests12 { +>Tests12 : Symbol(Tests12, Decl(typeofThis.ts, 121, 1)) + + test1() { // OK +>test1 : Symbol(Tests12.test1, Decl(typeofThis.ts, 123, 15)) + + type Test = typeof this; +>Test : Symbol(Test, Decl(typeofThis.ts, 124, 13)) + } + + test2() { // OK +>test2 : Symbol(Tests12.test2, Decl(typeofThis.ts, 126, 5)) + + for (;;) {} + type Test = typeof this; +>Test : Symbol(Test, Decl(typeofThis.ts, 129, 19)) + } + + test3() { // expected no compile errors +>test3 : Symbol(Tests12.test3, Decl(typeofThis.ts, 131, 5)) + + for (const dummy in []) {} +>dummy : Symbol(dummy, Decl(typeofThis.ts, 134, 18)) + + type Test = typeof this; +>Test : Symbol(Test, Decl(typeofThis.ts, 134, 34)) + } + + test4() { // expected no compile errors +>test4 : Symbol(Tests12.test4, Decl(typeofThis.ts, 136, 5)) + + for (const dummy of []) {} +>dummy : Symbol(dummy, Decl(typeofThis.ts, 139, 18)) + + type Test = typeof this; +>Test : Symbol(Test, Decl(typeofThis.ts, 139, 34)) + } +} diff --git a/tests/baselines/reference/typeofThis.types b/tests/baselines/reference/typeofThis.types index 61d8c8080eea9..5234d97282c6e 100644 --- a/tests/baselines/reference/typeofThis.types +++ b/tests/baselines/reference/typeofThis.types @@ -377,3 +377,48 @@ class Test11 { } } } + +class Tests12 { +>Tests12 : Tests12 + + test1() { // OK +>test1 : () => void + + type Test = typeof this; +>Test : this +>this : any + } + + test2() { // OK +>test2 : () => void + + for (;;) {} + type Test = typeof this; +>Test : this +>this : any + } + + test3() { // expected no compile errors +>test3 : () => void + + for (const dummy in []) {} +>dummy : string +>[] : never[] + + type Test = typeof this; +>Test : this +>this : any + } + + test4() { // expected no compile errors +>test4 : () => void + + for (const dummy of []) {} +>dummy : never +>[] : never[] + + type Test = typeof this; +>Test : this +>this : any + } +} diff --git a/tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts b/tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts index 78eb779147ae2..420604c55072d 100644 --- a/tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts +++ b/tests/cases/conformance/types/specifyingTypes/typeQueries/typeofThis.ts @@ -122,4 +122,25 @@ class Test11 { let y: string = o.this.x; // should narrow to string } } +} + +class Tests12 { + test1() { // OK + type Test = typeof this; + } + + test2() { // OK + for (;;) {} + type Test = typeof this; + } + + test3() { // expected no compile errors + for (const dummy in []) {} + type Test = typeof this; + } + + test4() { // expected no compile errors + for (const dummy of []) {} + type Test = typeof this; + } } \ No newline at end of file