@@ -8449,11 +8449,18 @@ namespace ts {
84498449
84508450 function instantiateList<T>(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] {
84518451 if (items && items.length) {
8452- const result: T[] = [];
8453- for (const v of items) {
8454- result.push(instantiator(v, mapper));
8452+ for (let i = 0; i < items.length; i++) {
8453+ const item = items[i];
8454+ const mapped = instantiator(item, mapper);
8455+ if (item !== mapped) {
8456+ const result = i === 0 ? [] : items.slice(0, i);
8457+ result.push(mapped);
8458+ for (i++; i < items.length; i++) {
8459+ result.push(instantiator(items[i], mapper));
8460+ }
8461+ return result;
8462+ }
84558463 }
8456- return result;
84578464 }
84588465 return items;
84598466 }
@@ -8583,8 +8590,13 @@ namespace ts {
85838590 }
85848591
85858592 function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol {
8593+ const links = getSymbolLinks(symbol);
8594+ if (links.type && !maybeTypeOfKind(links.type, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.Index)) {
8595+ // If the type of the symbol is already resolved, and if that type could not possibly
8596+ // be affected by instantiation, simply return the symbol itself.
8597+ return symbol;
8598+ }
85868599 if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
8587- const links = getSymbolLinks(symbol);
85888600 // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
85898601 // type mappers. This ensures that original type identities are properly preserved and that aliases
85908602 // always reference a non-aliases.
@@ -8748,14 +8760,20 @@ namespace ts {
87488760 return getAnonymousTypeInstantiation(<MappedType>type, mapper);
87498761 }
87508762 if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
8751- return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
8763+ const typeArguments = (<TypeReference>type).typeArguments;
8764+ const newTypeArguments = instantiateTypes(typeArguments, mapper);
8765+ return newTypeArguments !== typeArguments ? createTypeReference((<TypeReference>type).target, newTypeArguments) : type;
87528766 }
87538767 }
87548768 if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
8755- return getUnionType(instantiateTypes((<UnionType>type).types, mapper), UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8769+ const types = (<UnionType>type).types;
8770+ const newTypes = instantiateTypes(types, mapper);
8771+ return newTypes !== types ? getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
87568772 }
87578773 if (type.flags & TypeFlags.Intersection) {
8758- return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8774+ const types = (<IntersectionType>type).types;
8775+ const newTypes = instantiateTypes(types, mapper);
8776+ return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
87598777 }
87608778 if (type.flags & TypeFlags.Index) {
87618779 return getIndexType(instantiateType((<IndexType>type).type, mapper));
0 commit comments