diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6385d150a3e8e..9e4b759882502 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -83,6 +83,7 @@ namespace ts { const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); const keyofStringsOnly = !!compilerOptions.keyofStringsOnly; const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : ObjectFlags.FreshLiteral; + const maxInstantiationDepth = compilerOptions.maxInstantiationDepth || 50; const emitResolver = createResolver(); const nodeBuilder = createNodeBuilder(); @@ -10939,10 +10940,12 @@ namespace ts { if (!type || !mapper || mapper === identityMapper) { return type; } - if (instantiationDepth === 50) { - // We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing + if (instantiationDepth === maxInstantiationDepth) { + // We have reached too many recursive type instantiations and there is a very high likelyhood we're dealing // with a combination of infinite generic types that perpetually generate new type identities. We stop // the recursion here by yielding the error type. + // If stopping is undesirable, consider simplfying the type + // or increasing maxInstantiationDepth. return errorType; } instantiationDepth++; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 43275605e2390..1d2953114b661 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -768,6 +768,11 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file }, + { + name: "maxInstantiationDepth", + type: "number", + category: Diagnostics.Advanced_Options, + }, { name: "maxNodeModuleJsDepth", type: "number", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 863c54486154a..32f7518f64e83 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4530,6 +4530,7 @@ namespace ts { /*@internal*/listFiles?: boolean; locale?: string; mapRoot?: string; + maxInstantiationDepth?: number; maxNodeModuleJsDepth?: number; module?: ModuleKind; moduleResolution?: ModuleResolutionKind; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ae457551a5003..df52ee6b0ef5e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2466,6 +2466,7 @@ declare namespace ts { lib?: string[]; locale?: string; mapRoot?: string; + maxInstantiationDepth?: number; maxNodeModuleJsDepth?: number; module?: ModuleKind; moduleResolution?: ModuleResolutionKind; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a7dd2892a238c..0e5fd392fdddf 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2466,6 +2466,7 @@ declare namespace ts { lib?: string[]; locale?: string; mapRoot?: string; + maxInstantiationDepth?: number; maxNodeModuleJsDepth?: number; module?: ModuleKind; moduleResolution?: ModuleResolutionKind; diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/maxInstantiationDepth/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/maxInstantiationDepth/tsconfig.json new file mode 100644 index 0000000000000..52ad25843812a --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/maxInstantiationDepth/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "maxInstantiationDepth": 0 + } +}