@@ -8330,11 +8330,18 @@ namespace ts {
83308330
83318331 function instantiateList<T>(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] {
83328332 if (items && items.length) {
8333- const result: T[] = [];
8334- for (const v of items) {
8335- result.push(instantiator(v, mapper));
8333+ for (let i = 0; i < items.length; i++) {
8334+ const item = items[i];
8335+ const mapped = instantiator(item, mapper);
8336+ if (item !== mapped) {
8337+ const result = i === 0 ? [] : items.slice(0, i);
8338+ result.push(mapped);
8339+ for (i++; i < items.length; i++) {
8340+ result.push(instantiator(items[i], mapper));
8341+ }
8342+ return result;
8343+ }
83368344 }
8337- return result;
83388345 }
83398346 return items;
83408347 }
@@ -8456,8 +8463,13 @@ namespace ts {
84568463 }
84578464
84588465 function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol {
8466+ const links = getSymbolLinks(symbol);
8467+ if (links.type && !maybeTypeOfKind(links.type, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.Index)) {
8468+ // If the type of the symbol is already resolved, and if that type could not possibly
8469+ // be affected by instantiation, simply return the symbol itself.
8470+ return symbol;
8471+ }
84598472 if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
8460- const links = getSymbolLinks(symbol);
84618473 // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
84628474 // type mappers. This ensures that original type identities are properly preserved and that aliases
84638475 // always reference a non-aliases.
@@ -8600,14 +8612,20 @@ namespace ts {
86008612 return getAnonymousTypeInstantiation(<MappedType>type, mapper);
86018613 }
86028614 if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
8603- return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
8615+ const typeArguments = (<TypeReference>type).typeArguments;
8616+ const newTypeArguments = instantiateTypes(typeArguments, mapper);
8617+ return newTypeArguments !== typeArguments ? createTypeReference((<TypeReference>type).target, newTypeArguments) : type;
86048618 }
86058619 }
86068620 if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
8607- return getUnionType(instantiateTypes((<UnionType>type).types, mapper), UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8621+ const types = (<UnionType>type).types;
8622+ const newTypes = instantiateTypes(types, mapper);
8623+ return newTypes !== types ? getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
86088624 }
86098625 if (type.flags & TypeFlags.Intersection) {
8610- return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8626+ const types = (<IntersectionType>type).types;
8627+ const newTypes = instantiateTypes(types, mapper);
8628+ return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
86118629 }
86128630 if (type.flags & TypeFlags.Index) {
86138631 return getIndexType(instantiateType((<IndexType>type).type, mapper));
0 commit comments