From b8ee3307b24111225a292297a291e53543c2317e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 4 Nov 2021 17:13:04 -0700 Subject: [PATCH] [release-4.5] Exclude identity relation from mapped type relation check (#46635) * Exclude identity relation from mapped type relation check * Add regression test Co-authored-by: Anders Hejlsberg --- src/compiler/checker.ts | 2 +- .../noExcessiveStackDepthError.errors.txt | 22 ++++++++++ .../reference/noExcessiveStackDepthError.js | 34 +++++++++++++++ .../noExcessiveStackDepthError.symbols | 43 +++++++++++++++++++ .../noExcessiveStackDepthError.types | 24 +++++++++++ .../compiler/noExcessiveStackDepthError.ts | 17 ++++++++ 6 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/noExcessiveStackDepthError.errors.txt create mode 100644 tests/baselines/reference/noExcessiveStackDepthError.js create mode 100644 tests/baselines/reference/noExcessiveStackDepthError.symbols create mode 100644 tests/baselines/reference/noExcessiveStackDepthError.types create mode 100644 tests/cases/compiler/noExcessiveStackDepthError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6da38b533b3d8..b6e35f7d6c8e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19047,7 +19047,7 @@ namespace ts { originalErrorInfo = undefined; } } - else if (isGenericMappedType(target)) { + else if (isGenericMappedType(target) && relation !== identityRelation) { // Check if source type `S` is related to target type `{ [P in Q]: T }` or `{ [P in Q as R]: T}`. const keysRemapped = !!target.declaration.nameType; const templateType = getTemplateTypeFromMappedType(target); diff --git a/tests/baselines/reference/noExcessiveStackDepthError.errors.txt b/tests/baselines/reference/noExcessiveStackDepthError.errors.txt new file mode 100644 index 0000000000000..ae5f77e60dc91 --- /dev/null +++ b/tests/baselines/reference/noExcessiveStackDepthError.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/noExcessiveStackDepthError.ts(13,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'FindConditions', but here has type 'FindConditions'. + + +==== tests/cases/compiler/noExcessiveStackDepthError.ts (1 errors) ==== + // Repro from #46631 + + interface FindOperator { + foo: T; + } + + type FindConditions = { + [P in keyof T]?: FindConditions | FindOperator>; + }; + + function foo() { + var x: FindConditions; + var x: FindConditions; // Excessive stack depth error not expected here + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'FindConditions', but here has type 'FindConditions'. +!!! related TS6203 tests/cases/compiler/noExcessiveStackDepthError.ts:12:9: 'x' was also declared here. + } + \ No newline at end of file diff --git a/tests/baselines/reference/noExcessiveStackDepthError.js b/tests/baselines/reference/noExcessiveStackDepthError.js new file mode 100644 index 0000000000000..97e9cb944648b --- /dev/null +++ b/tests/baselines/reference/noExcessiveStackDepthError.js @@ -0,0 +1,34 @@ +//// [noExcessiveStackDepthError.ts] +// Repro from #46631 + +interface FindOperator { + foo: T; +} + +type FindConditions = { + [P in keyof T]?: FindConditions | FindOperator>; +}; + +function foo() { + var x: FindConditions; + var x: FindConditions; // Excessive stack depth error not expected here +} + + +//// [noExcessiveStackDepthError.js] +"use strict"; +// Repro from #46631 +function foo() { + var x; + var x; // Excessive stack depth error not expected here +} + + +//// [noExcessiveStackDepthError.d.ts] +interface FindOperator { + foo: T; +} +declare type FindConditions = { + [P in keyof T]?: FindConditions | FindOperator>; +}; +declare function foo(): void; diff --git a/tests/baselines/reference/noExcessiveStackDepthError.symbols b/tests/baselines/reference/noExcessiveStackDepthError.symbols new file mode 100644 index 0000000000000..441d59cac7998 --- /dev/null +++ b/tests/baselines/reference/noExcessiveStackDepthError.symbols @@ -0,0 +1,43 @@ +=== tests/cases/compiler/noExcessiveStackDepthError.ts === +// Repro from #46631 + +interface FindOperator { +>FindOperator : Symbol(FindOperator, Decl(noExcessiveStackDepthError.ts, 0, 0)) +>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 2, 23)) + + foo: T; +>foo : Symbol(FindOperator.foo, Decl(noExcessiveStackDepthError.ts, 2, 27)) +>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 2, 23)) +} + +type FindConditions = { +>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1)) +>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20)) + + [P in keyof T]?: FindConditions | FindOperator>; +>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5)) +>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20)) +>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1)) +>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20)) +>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5)) +>FindOperator : Symbol(FindOperator, Decl(noExcessiveStackDepthError.ts, 0, 0)) +>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1)) +>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20)) +>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5)) + +}; + +function foo() { +>foo : Symbol(foo, Decl(noExcessiveStackDepthError.ts, 8, 2)) +>Entity : Symbol(Entity, Decl(noExcessiveStackDepthError.ts, 10, 13)) + + var x: FindConditions; +>x : Symbol(x, Decl(noExcessiveStackDepthError.ts, 11, 7), Decl(noExcessiveStackDepthError.ts, 12, 7)) +>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1)) + + var x: FindConditions; // Excessive stack depth error not expected here +>x : Symbol(x, Decl(noExcessiveStackDepthError.ts, 11, 7), Decl(noExcessiveStackDepthError.ts, 12, 7)) +>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1)) +>Entity : Symbol(Entity, Decl(noExcessiveStackDepthError.ts, 10, 13)) +} + diff --git a/tests/baselines/reference/noExcessiveStackDepthError.types b/tests/baselines/reference/noExcessiveStackDepthError.types new file mode 100644 index 0000000000000..b468f6dad17e1 --- /dev/null +++ b/tests/baselines/reference/noExcessiveStackDepthError.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/noExcessiveStackDepthError.ts === +// Repro from #46631 + +interface FindOperator { + foo: T; +>foo : T +} + +type FindConditions = { +>FindConditions : FindConditions + + [P in keyof T]?: FindConditions | FindOperator>; +}; + +function foo() { +>foo : () => void + + var x: FindConditions; +>x : FindConditions + + var x: FindConditions; // Excessive stack depth error not expected here +>x : FindConditions +} + diff --git a/tests/cases/compiler/noExcessiveStackDepthError.ts b/tests/cases/compiler/noExcessiveStackDepthError.ts new file mode 100644 index 0000000000000..48f726a94dfcc --- /dev/null +++ b/tests/cases/compiler/noExcessiveStackDepthError.ts @@ -0,0 +1,17 @@ +// @strict: true +// @declaration: true + +// Repro from #46631 + +interface FindOperator { + foo: T; +} + +type FindConditions = { + [P in keyof T]?: FindConditions | FindOperator>; +}; + +function foo() { + var x: FindConditions; + var x: FindConditions; // Excessive stack depth error not expected here +}