diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index afd2b50c871..2a0c4eee988 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4465,7 +4465,7 @@ namespace ts { prop.type = instantiateType(target.templateType, templateMapper); members[propName] = prop; } - }) + }); setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); } @@ -6122,6 +6122,11 @@ namespace ts { return items; } + function instantiateCached(type: T, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T { + const instantiations = mapper.instantiations || (mapper.instantiations = []); + return instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper)); + } + function createUnaryTypeMapper(source: Type, target: Type): TypeMapper { return t => t === source ? target : t; } @@ -6261,28 +6266,11 @@ namespace ts { } function instantiateAnonymousOrMappedType(type: AnonymousType | MappedType, mapper: TypeMapper): ObjectType { - if (type.objectFlags & ObjectFlags.Instantiated) { - // If the type being instantiated is itself a instantiation, fetch the original target and - // combine the type mappers. - mapper = combineTypeMappers(type.mapper, mapper); - type = type.target; - } - if (mapper.instantiations) { - const cachedType = mapper.instantiations[type.id]; - if (cachedType) { - return cachedType; - } - } - else { - mapper.instantiations = []; - } - // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it const result = createObjectType(type.objectFlags | ObjectFlags.Instantiated, type.symbol); - result.target = type; - result.mapper = mapper; + result.target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type; + result.mapper = type.objectFlags & ObjectFlags.Instantiated ? combineTypeMappers(type.mapper, mapper) : mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = mapper.targetTypes; - mapper.instantiations[type.id] = result; return result; } @@ -6354,10 +6342,10 @@ namespace ts { return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && ((type).objectFlags & ObjectFlags.Instantiated || isSymbolInScopeOfMappedTypeParameter(type.symbol, mapper)) ? - instantiateAnonymousOrMappedType(type, mapper) : type; + instantiateCached(type, mapper, instantiateAnonymousOrMappedType) : type; } if ((type).objectFlags & ObjectFlags.Mapped) { - return instantiateAnonymousOrMappedType(type, mapper); + return instantiateCached(type, mapper, instantiateAnonymousOrMappedType); } if ((type).objectFlags & ObjectFlags.Reference) { return createTypeReference((type).target, instantiateList((type).typeArguments, mapper, instantiateType));