diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index 4592b3c656c43..0185968b996ed 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -81,6 +81,7 @@ type NodeBuilderContext struct { inferTypeParameters []*Type visitedTypes collections.Set[TypeId] symbolDepth map[CompositeSymbolIdentity]int + containerDepth int trackedSymbols []*TrackedSymbolArgs mapper *TypeMapper reverseMappedStack []*ast.Symbol @@ -3245,6 +3246,14 @@ func (b *NodeBuilderImpl) visitAndTransformType(t *Type, transform func(b *NodeB if b.ctx.visitedTypes.Has(typeId) { return b.createCyclicStructurePlaceholder() } + if isArrayOrTuple { + if b.ctx.containerDepth >= 20 { + b.ctx.truncating = true + return b.createElidedInformationPlaceholder() + } + b.ctx.containerDepth++ + defer func() { b.ctx.containerDepth-- }() + } isConstructorObject := t.objectFlags&ObjectFlagsAnonymous != 0 && t.symbol != nil && t.symbol.Flags&ast.SymbolFlagsClass != 0 var id *CompositeSymbolIdentity diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.errors.txt b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.errors.txt new file mode 100644 index 0000000000000..5ce65883e254f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.errors.txt @@ -0,0 +1,10 @@ +recursiveArrayTupleDeclarationEmit.ts(3,14): error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. + + +==== recursiveArrayTupleDeclarationEmit.ts (1 errors) ==== + type G = T extends unknown ? (T | G<[T]>)[] : never; + declare const g: G<"x">; + export const h = g; + ~ +!!! error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.js b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.js new file mode 100644 index 0000000000000..183fd19e85435 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.js @@ -0,0 +1,10 @@ +//// [tests/cases/compiler/recursiveArrayTupleDeclarationEmit.ts] //// + +//// [recursiveArrayTupleDeclarationEmit.ts] +type G = T extends unknown ? (T | G<[T]>)[] : never; +declare const g: G<"x">; +export const h = g; + + +//// [recursiveArrayTupleDeclarationEmit.js] +export const h = g; diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.symbols b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.symbols new file mode 100644 index 0000000000000..7684258cdecaa --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/recursiveArrayTupleDeclarationEmit.ts] //// + +=== recursiveArrayTupleDeclarationEmit.ts === +type G = T extends unknown ? (T | G<[T]>)[] : never; +>G : Symbol(G, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 7)) +>T : Symbol(T, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 7)) +>T : Symbol(T, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 7)) +>G : Symbol(G, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 7)) + +declare const g: G<"x">; +>g : Symbol(g, Decl(recursiveArrayTupleDeclarationEmit.ts, 1, 13)) +>G : Symbol(G, Decl(recursiveArrayTupleDeclarationEmit.ts, 0, 0)) + +export const h = g; +>h : Symbol(h, Decl(recursiveArrayTupleDeclarationEmit.ts, 2, 12)) +>g : Symbol(g, Decl(recursiveArrayTupleDeclarationEmit.ts, 1, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.types b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.types new file mode 100644 index 0000000000000..9e966d6903e34 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleDeclarationEmit.types @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/recursiveArrayTupleDeclarationEmit.ts] //// + +=== recursiveArrayTupleDeclarationEmit.ts === +type G = T extends unknown ? (T | G<[T]>)[] : never; +>G : G + +declare const g: G<"x">; +>g : ("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[] + +export const h = g; +>h : ("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[] +>g : ("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[] + diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.errors.txt b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.errors.txt new file mode 100644 index 0000000000000..0c5cd9657f4b9 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.errors.txt @@ -0,0 +1,14 @@ +recursiveArrayTupleTypePrinting.ts(3,14): error TS2322: Type '("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[]' is not assignable to type 'number'. +recursiveArrayTupleTypePrinting.ts(4,14): error TS2322: Type 'string' is not assignable to type 'number'. + + +==== recursiveArrayTupleTypePrinting.ts (2 errors) ==== + type G = T extends unknown ? (T | G<[T]>)[] : never; + declare const g: G<"x">; + export const n: number = g; + ~ +!!! error TS2322: Type '("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[]' is not assignable to type 'number'. + export const later: number = "oops"; + ~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.symbols b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.symbols new file mode 100644 index 0000000000000..d8852ac527a8f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.symbols @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/recursiveArrayTupleTypePrinting.ts] //// + +=== recursiveArrayTupleTypePrinting.ts === +type G = T extends unknown ? (T | G<[T]>)[] : never; +>G : Symbol(G, Decl(recursiveArrayTupleTypePrinting.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveArrayTupleTypePrinting.ts, 0, 7)) +>T : Symbol(T, Decl(recursiveArrayTupleTypePrinting.ts, 0, 7)) +>T : Symbol(T, Decl(recursiveArrayTupleTypePrinting.ts, 0, 7)) +>G : Symbol(G, Decl(recursiveArrayTupleTypePrinting.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveArrayTupleTypePrinting.ts, 0, 7)) + +declare const g: G<"x">; +>g : Symbol(g, Decl(recursiveArrayTupleTypePrinting.ts, 1, 13)) +>G : Symbol(G, Decl(recursiveArrayTupleTypePrinting.ts, 0, 0)) + +export const n: number = g; +>n : Symbol(n, Decl(recursiveArrayTupleTypePrinting.ts, 2, 12)) +>g : Symbol(g, Decl(recursiveArrayTupleTypePrinting.ts, 1, 13)) + +export const later: number = "oops"; +>later : Symbol(later, Decl(recursiveArrayTupleTypePrinting.ts, 3, 12)) + diff --git a/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.types b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.types new file mode 100644 index 0000000000000..af43b228b364d --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/recursiveArrayTupleTypePrinting.types @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/recursiveArrayTupleTypePrinting.ts] //// + +=== recursiveArrayTupleTypePrinting.ts === +type G = T extends unknown ? (T | G<[T]>)[] : never; +>G : G + +declare const g: G<"x">; +>g : ("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[] + +export const n: number = g; +>n : number +>g : ("x" | (((((((((((((((((((any | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[] | any)[])[] + +export const later: number = "oops"; +>later : number +>"oops" : "oops" + diff --git a/tsc/testdata/tests/cases/compiler/recursiveArrayTupleDeclarationEmit.ts b/tsc/testdata/tests/cases/compiler/recursiveArrayTupleDeclarationEmit.ts new file mode 100644 index 0000000000000..7172cd837a6c3 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/recursiveArrayTupleDeclarationEmit.ts @@ -0,0 +1,6 @@ +// @strict: true +// @declaration: true + +type G = T extends unknown ? (T | G<[T]>)[] : never; +declare const g: G<"x">; +export const h = g; diff --git a/tsc/testdata/tests/cases/compiler/recursiveArrayTupleTypePrinting.ts b/tsc/testdata/tests/cases/compiler/recursiveArrayTupleTypePrinting.ts new file mode 100644 index 0000000000000..53b0cb44cd1d0 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/recursiveArrayTupleTypePrinting.ts @@ -0,0 +1,8 @@ +// @strict: true +// @noErrorTruncation: true +// @noEmit: true + +type G = T extends unknown ? (T | G<[T]>)[] : never; +declare const g: G<"x">; +export const n: number = g; +export const later: number = "oops";