@@ -10096,31 +10096,12 @@ namespace ts {
10096
10096
inferTypes(context.signature.typeParameters, context.inferences, originalSource, originalTarget);
10097
10097
}
10098
10098
10099
- function getSymbolForInference(type: Type) {
10100
- // Exclude the static side of classes since it shares its symbol with the instance side which leads
10101
- // to false positives.
10102
- return type.flags & TypeFlags.Object && !(getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class) ? type.symbol : undefined;
10103
- }
10104
-
10105
10099
function inferTypes(typeVariables: TypeVariable[], typeInferences: TypeInferences[], originalSource: Type, originalTarget: Type) {
10106
- let stack: Type [];
10107
- let depth = 0 ;
10100
+ let symbolStack: Symbol [];
10101
+ let visited: Map<boolean> ;
10108
10102
let inferiority = 0;
10109
- const visited = createMap<boolean>();
10110
10103
inferFromTypes(originalSource, originalTarget);
10111
10104
10112
- function isInstantiationInProcess(type: Type) {
10113
- const symbol = getSymbolForInference(type);
10114
- if (symbol) {
10115
- for (let i = 0; i < depth; i++) {
10116
- const t = stack[i];
10117
- if (getSymbolForInference(t) === symbol) {
10118
- return true;
10119
- }
10120
- }
10121
- }
10122
- }
10123
-
10124
10105
function inferFromTypes(source: Type, target: Type) {
10125
10106
if (!couldContainTypeVariables(target)) {
10126
10107
return;
@@ -10248,21 +10229,29 @@ namespace ts {
10248
10229
else {
10249
10230
source = getApparentType(source);
10250
10231
if (source.flags & TypeFlags.Object) {
10232
+ const key = source.id + "," + target.id;
10233
+ if (visited && visited.get(key)) {
10234
+ return;
10235
+ }
10236
+ (visited || (visited = createMap<boolean>())).set(key, true);
10251
10237
// If we are already processing another target type with the same associated symbol (such as
10252
10238
// an instantiation of the same generic type), we do not explore this target as it would yield
10253
- // no further inferences.
10254
- if (isInstantiationInProcess(target)) {
10255
- return;
10239
+ // no further inferences. We exclude the static side of classes from this check since it shares
10240
+ // its symbol with the instance side which would lead to false positives.
10241
+ const isNonConstructorObject = target.flags & TypeFlags.Object &&
10242
+ !(getObjectFlags(target) & ObjectFlags.Anonymous && target.symbol && target.symbol.flags & SymbolFlags.Class);
10243
+ const symbol = isNonConstructorObject ? target.symbol : undefined;
10244
+ if (symbol) {
10245
+ if (contains(symbolStack, symbol)) {
10246
+ return;
10247
+ }
10248
+ (symbolStack || (symbolStack = [])).push(symbol);
10249
+ inferFromObjectTypes(source, target);
10250
+ symbolStack.pop();
10256
10251
}
10257
- const key = source.id + "," + target.id;
10258
- if (visited.get(key)) {
10259
- return;
10252
+ else {
10253
+ inferFromObjectTypes(source, target);
10260
10254
}
10261
- visited.set(key, true);
10262
- (stack || (stack = []))[depth] = target;
10263
- depth++;
10264
- inferFromObjectTypes(source, target);
10265
- depth--;
10266
10255
}
10267
10256
}
10268
10257
}
0 commit comments