@@ -9190,6 +9190,39 @@ namespace ts {
9190
9190
return result;
9191
9191
}
9192
9192
9193
+ function checkTypeReferenceMaybeStack(source: Type, target: Type): Ternary {
9194
+ if (!(getObjectFlags(source) & ObjectFlags.Reference) || !(getObjectFlags(target) & ObjectFlags.Reference)) {
9195
+ return Ternary.False;
9196
+ }
9197
+ const sourceArguments = (source as TypeReference).typeArguments;
9198
+ const targetArguments = (source as TypeReference).typeArguments;
9199
+ const sourceGeneric = (source as TypeReference).target;
9200
+ const targetGeneric = (source as TypeReference).target;
9201
+
9202
+ const onlyTypeParametersAsArguments =
9203
+ arrayIsEqualTo(sourceArguments, targetArguments) &&
9204
+ sourceArguments && sourceArguments.length > 0 &&
9205
+ every(sourceArguments, t => !!(t.flags & TypeFlags.TypeParameter));
9206
+ if (!onlyTypeParametersAsArguments) {
9207
+ return Ternary.False;
9208
+ }
9209
+ const id = (relation !== identityRelation || sourceGeneric.id < targetGeneric.id ? sourceGeneric.id + "," + targetGeneric.id : targetGeneric.id + "," + sourceGeneric.id) +
9210
+ "<" + map(sourceArguments, t => { let c = getConstraintFromTypeParameter(t as TypeParameter); return c ? c.id : "" }).join(',') + ">";
9211
+ if (!maybeReferenceKeys) {
9212
+ maybeReferenceKeys = [];
9213
+ }
9214
+ else {
9215
+ for (let i = 0; i < maybeReferenceCount; i++) {
9216
+ if (id === maybeReferenceKeys[i]) {
9217
+ return Ternary.Maybe;
9218
+ }
9219
+ }
9220
+ }
9221
+ maybeReferenceKeys[maybeReferenceCount] = id;
9222
+ maybeReferenceCount++;
9223
+ return Ternary.False;
9224
+ }
9225
+
9193
9226
// Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
9194
9227
// Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
9195
9228
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
@@ -9200,29 +9233,6 @@ namespace ts {
9200
9233
return Ternary.False;
9201
9234
}
9202
9235
9203
- if (getObjectFlags(source) & ObjectFlags.Reference &&
9204
- getObjectFlags(target) & ObjectFlags.Reference &&
9205
- (source as TypeReference).typeArguments && (source as TypeReference).typeArguments.length > 0 &&
9206
- arrayIsEqualTo((source as TypeReference).typeArguments, (target as TypeReference).typeArguments, (a1, m1) => a1 === m1)) {
9207
- // Same type arguments, let's see if we've already seen this pair before
9208
- // this is a copy of the normal code! It can probably be merged somehow.
9209
- const src = (source as TypeReference).target;
9210
- const trg = (target as TypeReference).target;
9211
- const id = relation !== identityRelation || src.id < trg.id ? src.id + "," + trg.id : trg.id + "," + src.id;
9212
- if (!maybeReferenceKeys) {
9213
- maybeReferenceKeys = [];
9214
- }
9215
- else {
9216
- for (let i = 0; i < maybeReferenceCount; i++) {
9217
- if (id === maybeReferenceKeys[i]) {
9218
- return Ternary.Maybe;
9219
- }
9220
- }
9221
- }
9222
- maybeReferenceKeys[maybeReferenceCount] = id;
9223
- maybeReferenceCount++;
9224
- }
9225
-
9226
9236
const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
9227
9237
const related = relation.get(id);
9228
9238
if (related !== undefined) {
@@ -9253,6 +9263,10 @@ namespace ts {
9253
9263
return Ternary.False;
9254
9264
}
9255
9265
}
9266
+ if (checkTypeReferenceMaybeStack(source, target) === Ternary.Maybe) {
9267
+ return Ternary.Maybe;
9268
+ }
9269
+
9256
9270
const maybeStart = maybeCount;
9257
9271
maybeKeys[maybeCount] = id;
9258
9272
maybeCount++;
0 commit comments