Skip to content

Commit 7cbcfee

Browse files
authored
Exclude identity relation from mapped type relation check (#46632)
* Exclude identity relation from mapped type relation check * Add regression test
1 parent 2424d0e commit 7cbcfee

6 files changed

+141
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19046,7 +19046,7 @@ namespace ts {
1904619046
originalErrorInfo = undefined;
1904719047
}
1904819048
}
19049-
else if (isGenericMappedType(target)) {
19049+
else if (isGenericMappedType(target) && relation !== identityRelation) {
1905019050
// Check if source type `S` is related to target type `{ [P in Q]: T }` or `{ [P in Q as R]: T}`.
1905119051
const keysRemapped = !!target.declaration.nameType;
1905219052
const templateType = getTemplateTypeFromMappedType(target);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
tests/cases/compiler/noExcessiveStackDepthError.ts(13,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'FindConditions<any>', but here has type 'FindConditions<Entity>'.
2+
3+
4+
==== tests/cases/compiler/noExcessiveStackDepthError.ts (1 errors) ====
5+
// Repro from #46631
6+
7+
interface FindOperator<T> {
8+
foo: T;
9+
}
10+
11+
type FindConditions<T> = {
12+
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
13+
};
14+
15+
function foo<Entity>() {
16+
var x: FindConditions<any>;
17+
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
18+
~
19+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'FindConditions<any>', but here has type 'FindConditions<Entity>'.
20+
!!! related TS6203 tests/cases/compiler/noExcessiveStackDepthError.ts:12:9: 'x' was also declared here.
21+
}
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//// [noExcessiveStackDepthError.ts]
2+
// Repro from #46631
3+
4+
interface FindOperator<T> {
5+
foo: T;
6+
}
7+
8+
type FindConditions<T> = {
9+
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
10+
};
11+
12+
function foo<Entity>() {
13+
var x: FindConditions<any>;
14+
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
15+
}
16+
17+
18+
//// [noExcessiveStackDepthError.js]
19+
"use strict";
20+
// Repro from #46631
21+
function foo() {
22+
var x;
23+
var x; // Excessive stack depth error not expected here
24+
}
25+
26+
27+
//// [noExcessiveStackDepthError.d.ts]
28+
interface FindOperator<T> {
29+
foo: T;
30+
}
31+
declare type FindConditions<T> = {
32+
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
33+
};
34+
declare function foo<Entity>(): void;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
=== tests/cases/compiler/noExcessiveStackDepthError.ts ===
2+
// Repro from #46631
3+
4+
interface FindOperator<T> {
5+
>FindOperator : Symbol(FindOperator, Decl(noExcessiveStackDepthError.ts, 0, 0))
6+
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 2, 23))
7+
8+
foo: T;
9+
>foo : Symbol(FindOperator.foo, Decl(noExcessiveStackDepthError.ts, 2, 27))
10+
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 2, 23))
11+
}
12+
13+
type FindConditions<T> = {
14+
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
15+
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
16+
17+
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
18+
>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5))
19+
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
20+
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
21+
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
22+
>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5))
23+
>FindOperator : Symbol(FindOperator, Decl(noExcessiveStackDepthError.ts, 0, 0))
24+
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
25+
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
26+
>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5))
27+
28+
};
29+
30+
function foo<Entity>() {
31+
>foo : Symbol(foo, Decl(noExcessiveStackDepthError.ts, 8, 2))
32+
>Entity : Symbol(Entity, Decl(noExcessiveStackDepthError.ts, 10, 13))
33+
34+
var x: FindConditions<any>;
35+
>x : Symbol(x, Decl(noExcessiveStackDepthError.ts, 11, 7), Decl(noExcessiveStackDepthError.ts, 12, 7))
36+
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
37+
38+
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
39+
>x : Symbol(x, Decl(noExcessiveStackDepthError.ts, 11, 7), Decl(noExcessiveStackDepthError.ts, 12, 7))
40+
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
41+
>Entity : Symbol(Entity, Decl(noExcessiveStackDepthError.ts, 10, 13))
42+
}
43+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/compiler/noExcessiveStackDepthError.ts ===
2+
// Repro from #46631
3+
4+
interface FindOperator<T> {
5+
foo: T;
6+
>foo : T
7+
}
8+
9+
type FindConditions<T> = {
10+
>FindConditions : FindConditions<T>
11+
12+
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
13+
};
14+
15+
function foo<Entity>() {
16+
>foo : <Entity>() => void
17+
18+
var x: FindConditions<any>;
19+
>x : FindConditions<any>
20+
21+
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
22+
>x : FindConditions<any>
23+
}
24+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @strict: true
2+
// @declaration: true
3+
4+
// Repro from #46631
5+
6+
interface FindOperator<T> {
7+
foo: T;
8+
}
9+
10+
type FindConditions<T> = {
11+
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
12+
};
13+
14+
function foo<Entity>() {
15+
var x: FindConditions<any>;
16+
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
17+
}

0 commit comments

Comments
 (0)