Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 79474fd

Browse filesBrowse files
authored
Increase type instantiation depth limit (microsoft#45025)
* Bump instantiation depth limit to 500 * Accept new baselines * Update tests * Accept new baselines
1 parent dc80e6a commit 79474fd
Copy full SHA for 79474fd

6 files changed

+245-241Lines changed: 245 additions & 241 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+12-19Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16272,28 +16272,21 @@ namespace ts {
1627216272
let result = root.instantiations!.get(id);
1627316273
if (!result) {
1627416274
const newMapper = createTypeMapper(root.outerTypeParameters, typeArguments);
16275-
result = instantiateConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments);
16275+
const checkType = root.checkType;
16276+
const distributionType = root.isDistributive ? getMappedType(checkType, newMapper) : undefined;
16277+
// Distributive conditional types are distributed over union types. For example, when the
16278+
// distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the
16279+
// result is (A extends U ? X : Y) | (B extends U ? X : Y).
16280+
result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ?
16281+
mapTypeWithAlias(distributionType, t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments) :
16282+
getConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments);
1627616283
root.instantiations!.set(id, result);
1627716284
}
1627816285
return result;
1627916286
}
1628016287
return type;
1628116288
}
1628216289

16283-
function instantiateConditionalType(root: ConditionalRoot, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
16284-
// Check if we have a conditional type where the check type is a naked type parameter. If so,
16285-
// the conditional type is distributive over union types and when T is instantiated to a union
16286-
// type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y).
16287-
if (root.isDistributive) {
16288-
const checkType = root.checkType as TypeParameter;
16289-
const instantiatedType = getMappedType(checkType, mapper);
16290-
if (checkType !== instantiatedType && instantiatedType.flags & (TypeFlags.Union | TypeFlags.Never)) {
16291-
return mapTypeWithAlias(instantiatedType, t => getConditionalType(root, prependTypeMapping(checkType, t, mapper)), aliasSymbol, aliasTypeArguments);
16292-
}
16293-
}
16294-
return getConditionalType(root, mapper, aliasSymbol, aliasTypeArguments);
16295-
}
16296-
1629716290
function instantiateType(type: Type, mapper: TypeMapper | undefined): Type;
1629816291
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined;
1629916292
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined {
@@ -16304,10 +16297,10 @@ namespace ts {
1630416297
if (!couldContainTypeVariables(type)) {
1630516298
return type;
1630616299
}
16307-
if (instantiationDepth === 50 || instantiationCount >= 5000000) {
16308-
// We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
16309-
// with a combination of infinite generic types that perpetually generate new type identities. We stop
16310-
// the recursion here by yielding the error type.
16300+
if (instantiationDepth === 500 || instantiationCount >= 5000000) {
16301+
// We have reached 500 recursive type instantiations, or 5M type instantiations caused by the same statement
16302+
// or expression. There is a very high likelyhood we're dealing with a combination of infinite generic types
16303+
// that perpetually generate new type identities, so we stop the recursion here by yielding the error type.
1631116304
tracing?.instant(tracing.Phase.CheckTypes, "instantiateType_DepthLimit", { typeId: type.id, instantiationDepth, instantiationCount });
1631216305
error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
1631316306
return errorType;
Collapse file

‎tests/baselines/reference/recursiveConditionalTypes.errors.txt‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/recursiveConditionalTypes.errors.txt
+7-6Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ tests/cases/compiler/recursiveConditionalTypes.ts(21,5): error TS2322: Type 'T'
66
tests/cases/compiler/recursiveConditionalTypes.ts(22,5): error TS2322: Type 'Awaited<T>' is not assignable to type 'T'.
77
'T' could be instantiated with an arbitrary type which could be unrelated to 'Awaited<T>'.
88
tests/cases/compiler/recursiveConditionalTypes.ts(35,11): error TS2589: Type instantiation is excessively deep and possibly infinite.
9-
tests/cases/compiler/recursiveConditionalTypes.ts(46,12): error TS2589: Type instantiation is excessively deep and possibly infinite.
10-
tests/cases/compiler/recursiveConditionalTypes.ts(49,5): error TS2322: Type 'TupleOf<number, M>' is not assignable to type 'TupleOf<number, N>'.
9+
tests/cases/compiler/recursiveConditionalTypes.ts(47,12): error TS2589: Type instantiation is excessively deep and possibly infinite.
10+
tests/cases/compiler/recursiveConditionalTypes.ts(50,5): error TS2322: Type 'TupleOf<number, M>' is not assignable to type 'TupleOf<number, N>'.
1111
Type 'number extends M ? number[] : _TupleOf<number, M, []>' is not assignable to type 'TupleOf<number, N>'.
1212
Type 'number[] | _TupleOf<number, M, []>' is not assignable to type 'TupleOf<number, N>'.
1313
Type 'number[]' is not assignable to type 'TupleOf<number, N>'.
14-
tests/cases/compiler/recursiveConditionalTypes.ts(50,5): error TS2322: Type 'TupleOf<number, N>' is not assignable to type 'TupleOf<number, M>'.
14+
tests/cases/compiler/recursiveConditionalTypes.ts(51,5): error TS2322: Type 'TupleOf<number, N>' is not assignable to type 'TupleOf<number, M>'.
1515
Type 'number extends N ? number[] : _TupleOf<number, N, []>' is not assignable to type 'TupleOf<number, M>'.
1616
Type 'number[] | _TupleOf<number, N, []>' is not assignable to type 'TupleOf<number, M>'.
1717
Type 'number[]' is not assignable to type 'TupleOf<number, M>'.
18-
tests/cases/compiler/recursiveConditionalTypes.ts(116,9): error TS2345: Argument of type 'Grow2<[], T>' is not assignable to parameter of type 'Grow1<[], T>'.
18+
tests/cases/compiler/recursiveConditionalTypes.ts(117,9): error TS2345: Argument of type 'Grow2<[], T>' is not assignable to parameter of type 'Grow1<[], T>'.
1919
Type '[] | Grow2<[string], T>' is not assignable to type 'Grow1<[], T>'.
2020
Type '[]' is not assignable to type 'Grow1<[], T>'.
2121
Type 'Grow2<[string], T>' is not assignable to type 'Grow1<[number], T>'.
@@ -84,8 +84,9 @@ tests/cases/compiler/recursiveConditionalTypes.ts(116,9): error TS2345: Argument
8484
type TT1 = TupleOf<number, 0 | 2 | 4>;
8585
type TT2 = TupleOf<number, number>;
8686
type TT3 = TupleOf<number, any>;
87-
type TT4 = TupleOf<number, 100>; // Depth error
88-
~~~~~~~~~~~~~~~~~~~~
87+
type TT4 = TupleOf<number, 100>;
88+
type TT5 = TupleOf<number, 1000>; // Depth error
89+
~~~~~~~~~~~~~~~~~~~~~
8990
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
9091

9192
function f22<N extends number, M extends N>(tn: TupleOf<number, N>, tm: TupleOf<number, M>) {
Collapse file

‎tests/baselines/reference/recursiveConditionalTypes.js‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/recursiveConditionalTypes.js
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ type TT0 = TupleOf<string, 4>;
4444
type TT1 = TupleOf<number, 0 | 2 | 4>;
4545
type TT2 = TupleOf<number, number>;
4646
type TT3 = TupleOf<number, any>;
47-
type TT4 = TupleOf<number, 100>; // Depth error
47+
type TT4 = TupleOf<number, 100>;
48+
type TT5 = TupleOf<number, 1000>; // Depth error
4849

4950
function f22<N extends number, M extends N>(tn: TupleOf<number, N>, tm: TupleOf<number, M>) {
5051
tn = tm;
@@ -194,6 +195,7 @@ declare type TT1 = TupleOf<number, 0 | 2 | 4>;
194195
declare type TT2 = TupleOf<number, number>;
195196
declare type TT3 = TupleOf<number, any>;
196197
declare type TT4 = TupleOf<number, 100>;
198+
declare type TT5 = TupleOf<number, 1000>;
197199
declare function f22<N extends number, M extends N>(tn: TupleOf<number, N>, tm: TupleOf<number, M>): void;
198200
declare function f23<T>(t: TupleOf<T, 3>): T;
199201
interface Box<T> {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.