Skip to content

Commit f2c5643

Browse files
authored
Flag mapped types with circular property types and do not attempt to print them structurally (#39552)
1 parent fcd4fcb commit f2c5643

7 files changed

+49
-2
lines changed

src/compiler/checker.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -4577,8 +4577,8 @@ namespace ts {
45774577
}
45784578

45794579
function createTypeNodeFromObjectType(type: ObjectType): TypeNode {
4580-
if (isGenericMappedType(type)) {
4581-
return createMappedTypeNodeFromType(type);
4580+
if (isGenericMappedType(type) || (type as MappedType).containsError) {
4581+
return createMappedTypeNodeFromType(type as MappedType);
45824582
}
45834583

45844584
const resolved = resolveStructuredTypeMembers(type);
@@ -10316,6 +10316,7 @@ namespace ts {
1031610316
function getTypeOfMappedSymbol(symbol: MappedSymbol) {
1031710317
if (!symbol.type) {
1031810318
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
10319+
symbol.mappedType.containsError = true;
1031910320
return errorType;
1032010321
}
1032110322
const templateType = getTemplateTypeFromMappedType(<MappedType>symbol.mappedType.target || symbol.mappedType);

src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5177,6 +5177,7 @@ namespace ts {
51775177
templateType?: Type;
51785178
modifiersType?: Type;
51795179
resolvedApparentType?: Type;
5180+
containsError?: boolean;
51805181
}
51815182

51825183
export interface EvolvingArrayType extends ObjectType {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts(3,10): error TS2589: Type instantiation is excessively deep and possibly infinite.
2+
tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts(3,10): error TS2615: Type of property 'M' circularly references itself in mapped type '{ [P in "M"]: any; }'.
3+
4+
5+
==== tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts (2 errors) ====
6+
type N<T, K extends string> = T | { [P in K]: N<T, K> }[K];
7+
8+
type M = N<number, "M">;
9+
~~~~~~~~~~~~~~
10+
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
11+
~~~~~~~~~~~~~~
12+
!!! error TS2615: Type of property 'M' circularly references itself in mapped type '{ [P in "M"]: any; }'.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [recursivelyExpandingUnionNoStackoverflow.ts]
2+
type N<T, K extends string> = T | { [P in K]: N<T, K> }[K];
3+
4+
type M = N<number, "M">;
5+
6+
//// [recursivelyExpandingUnionNoStackoverflow.js]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts ===
2+
type N<T, K extends string> = T | { [P in K]: N<T, K> }[K];
3+
>N : Symbol(N, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 0))
4+
>T : Symbol(T, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 7))
5+
>K : Symbol(K, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 9))
6+
>T : Symbol(T, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 7))
7+
>P : Symbol(P, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 37))
8+
>K : Symbol(K, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 9))
9+
>N : Symbol(N, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 0))
10+
>T : Symbol(T, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 7))
11+
>K : Symbol(K, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 9))
12+
>K : Symbol(K, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 9))
13+
14+
type M = N<number, "M">;
15+
>M : Symbol(M, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 59))
16+
>N : Symbol(N, Decl(recursivelyExpandingUnionNoStackoverflow.ts, 0, 0))
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
=== tests/cases/compiler/recursivelyExpandingUnionNoStackoverflow.ts ===
2+
type N<T, K extends string> = T | { [P in K]: N<T, K> }[K];
3+
>N : N<T, K>
4+
5+
type M = N<number, "M">;
6+
>M : any
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type N<T, K extends string> = T | { [P in K]: N<T, K> }[K];
2+
3+
type M = N<number, "M">;

0 commit comments

Comments
 (0)