diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8fa3c4fce2a4a..fb5fdf6069354 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17965,7 +17965,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.flags & TypeFlags.Any) { addElement(type, ElementFlags.Rest, target.labeledElementDeclarations?.[i]); } - else if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) { + else if (someContainedType(type, t => !!(t.flags & TypeFlags.InstantiableNonPrimitive) || isGenericMappedType(type))) { // Generic variadic elements stay as they are. addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]); } @@ -28515,6 +28515,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type.flags & TypeFlags.Union ? every((type as UnionType).types, f) : f(type); } + function someContainedType(type: Type, f: (t: Type) => boolean): boolean { + return type.flags & TypeFlags.UnionOrIntersection ? some((type as UnionOrIntersectionType).types, f) : f(type); + } + function everyContainedType(type: Type, f: (t: Type) => boolean): boolean { return type.flags & TypeFlags.UnionOrIntersection ? every((type as UnionOrIntersectionType).types, f) : f(type); } diff --git a/tests/baselines/reference/recursiveConditionalCrash5.errors.txt b/tests/baselines/reference/recursiveConditionalCrash5.errors.txt new file mode 100644 index 0000000000000..ac99cf2a6d542 --- /dev/null +++ b/tests/baselines/reference/recursiveConditionalCrash5.errors.txt @@ -0,0 +1,10 @@ +recursiveConditionalCrash5.ts(3,60): error TS2589: Type instantiation is excessively deep and possibly infinite. + + +==== recursiveConditionalCrash5.ts (1 errors) ==== + // https://github.com/microsoft/TypeScript/issues/63040 + + type StringTreeArrayAsTuple = (T extends [...infer R] ? [...StringTreeArrayAsTuple] : never) & boolean; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2589: Type instantiation is excessively deep and possibly infinite. + \ No newline at end of file diff --git a/tests/baselines/reference/recursiveConditionalCrash5.symbols b/tests/baselines/reference/recursiveConditionalCrash5.symbols new file mode 100644 index 0000000000000..088577dcd7b43 --- /dev/null +++ b/tests/baselines/reference/recursiveConditionalCrash5.symbols @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/recursiveConditionalCrash5.ts] //// + +=== recursiveConditionalCrash5.ts === +// https://github.com/microsoft/TypeScript/issues/63040 + +type StringTreeArrayAsTuple = (T extends [...infer R] ? [...StringTreeArrayAsTuple] : never) & boolean; +>StringTreeArrayAsTuple : Symbol(StringTreeArrayAsTuple, Decl(recursiveConditionalCrash5.ts, 0, 0)) +>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 2, 28)) +>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 2, 28)) +>R : Symbol(R, Decl(recursiveConditionalCrash5.ts, 2, 53)) +>StringTreeArrayAsTuple : Symbol(StringTreeArrayAsTuple, Decl(recursiveConditionalCrash5.ts, 0, 0)) +>R : Symbol(R, Decl(recursiveConditionalCrash5.ts, 2, 53)) + diff --git a/tests/baselines/reference/recursiveConditionalCrash5.types b/tests/baselines/reference/recursiveConditionalCrash5.types new file mode 100644 index 0000000000000..d920776cd72ed --- /dev/null +++ b/tests/baselines/reference/recursiveConditionalCrash5.types @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/recursiveConditionalCrash5.ts] //// + +=== recursiveConditionalCrash5.ts === +// https://github.com/microsoft/TypeScript/issues/63040 + +type StringTreeArrayAsTuple = (T extends [...infer R] ? [...StringTreeArrayAsTuple] : never) & boolean; +>StringTreeArrayAsTuple : StringTreeArrayAsTuple +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/cases/compiler/recursiveConditionalCrash5.ts b/tests/cases/compiler/recursiveConditionalCrash5.ts new file mode 100644 index 0000000000000..87641a5ca9277 --- /dev/null +++ b/tests/cases/compiler/recursiveConditionalCrash5.ts @@ -0,0 +1,6 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/63040 + +type StringTreeArrayAsTuple = (T extends [...infer R] ? [...StringTreeArrayAsTuple] : never) & boolean;