@@ -14056,7 +14056,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1405614056 if (getObjectFlags(type) & ObjectFlags.Reference) {
1405714057 const target = (type as TypeReference).target;
1405814058 const typeArguments = getTypeArguments(type as TypeReference);
14059- return length(target.typeParameters) === length(typeArguments) ? createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType!])) : type;
14059+ return length(target.typeParameters) === length(typeArguments) ? createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType!]), !!(getObjectFlags(type) & ObjectFlags.InstantiatedReference) ) : type;
1406014060 }
1406114061 else if (type.flags & TypeFlags.Intersection) {
1406214062 const types = sameMap((type as IntersectionType).types, t => getTypeWithThisArgument(t, thisArgument, needApparentType));
@@ -16919,13 +16919,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1691916919 return createTypeReference(target, typeArguments);
1692016920 }
1692116921
16922- function createTypeReference(target: GenericType, typeArguments: readonly Type[] | undefined): TypeReference {
16923- const id = getTypeListId(typeArguments);
16922+ function createTypeReference(target: GenericType, typeArguments: readonly Type[] | undefined, instantiatedReference?: boolean ): TypeReference {
16923+ const id = getTypeListId(typeArguments) + (instantiatedReference ? "*" : "") ;
1692416924 let type = target.instantiations.get(id);
1692516925 if (!type) {
1692616926 type = createObjectType(ObjectFlags.Reference, target.symbol) as TypeReference;
1692716927 target.instantiations.set(id, type);
1692816928 type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments) : 0;
16929+ if (instantiatedReference) {
16930+ type.objectFlags |= ObjectFlags.InstantiatedReference;
16931+ }
1692916932 type.target = target;
1693016933 type.resolvedTypeArguments = typeArguments;
1693116934 }
@@ -21064,7 +21067,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2106421067 if (objectFlags & ObjectFlags.Reference && !(type as TypeReference).node) {
2106521068 const resolvedTypeArguments = (type as TypeReference).resolvedTypeArguments;
2106621069 const newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper);
21067- return newTypeArguments !== resolvedTypeArguments ? createNormalizedTypeReference((type as TypeReference).target, newTypeArguments) : type;
21070+ return newTypeArguments === resolvedTypeArguments ? type :
21071+ (type as TypeReference).target.objectFlags & ObjectFlags.Tuple ? createNormalizedTupleType((type as TypeReference).target as TupleType, newTypeArguments!) :
21072+ createTypeReference((type as TypeReference).target, newTypeArguments, /*instantiatedReference*/ true);
2106821073 }
2106921074 if (objectFlags & ObjectFlags.ReverseMapped) {
2107021075 return instantiateReverseMappedType(type as ReverseMappedType, mapper);
@@ -25085,7 +25090,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2508525090 }
2508625091 const result = symbol.flags & SymbolFlags.TypeAlias ?
2508725092 getTypeAliasInstantiation(symbol, instantiateTypes(getSymbolLinks(symbol).typeParameters!, mapper)) :
25088- createTypeReference(type as GenericType, instantiateTypes((type as GenericType).typeParameters, mapper));
25093+ createTypeReference(type as GenericType, instantiateTypes((type as GenericType).typeParameters, mapper), /*instantiatedReference*/ true );
2508925094 markerTypes.add(getTypeId(result));
2509025095 return result;
2509125096 }
@@ -25300,35 +25305,37 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2530025305 function getRecursionIdentity(type: Type): object {
2530125306 // Object and array literals are known not to contain recursive references and don't need a recursion identity.
2530225307 if (type.flags & TypeFlags.Object && !isObjectOrArrayLiteralType(type)) {
25303- if (getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).node) {
25308+ const objectFlags = getObjectFlags(type);
25309+ if (objectFlags & ObjectFlags.Reference && (type as TypeReference).node) {
2530425310 // Deferred type references are tracked through their associated AST node. This gives us finer
2530525311 // granularity than using their associated target because each manifest type reference has a
2530625312 // unique AST node.
2530725313 return (type as TypeReference).node!;
2530825314 }
25309- if (type.symbol && !(getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol.flags & SymbolFlags.Class)) {
25310- // We track object types that have a symbol by that symbol (representing the origin of the type), but
25311- // exclude the static side of a class since it shares its symbol with the instance side.
25315+ if (type.symbol && objectFlags & (ObjectFlags.Instantiated|ObjectFlags.InstantiatedReference) &&
25316+ !(objectFlags & ObjectFlags.Anonymous && type.symbol.flags & SymbolFlags.Class)) {
25317+ // We track instantiated object types that have a symbol by that symbol (representing the origin of the
25318+ // type), but exclude the static side of a class since it shares its symbol with the instance side.
2531225319 return type.symbol;
2531325320 }
2531425321 if (isTupleType(type)) {
2531525322 return type.target;
2531625323 }
2531725324 }
25318- if (type.flags & TypeFlags.TypeParameter) {
25325+ else if (type.flags & TypeFlags.TypeParameter) {
2531925326 // We use the symbol of the type parameter such that all "fresh" instantiations of that type parameter
2532025327 // have the same recursion identity.
2532125328 return type.symbol;
2532225329 }
25323- if (type.flags & TypeFlags.IndexedAccess) {
25330+ else if (type.flags & TypeFlags.IndexedAccess) {
2532425331 // Identity is the leftmost object type in a chain of indexed accesses, eg, in A[P1][P2][P3] it is A.
2532525332 do {
2532625333 type = (type as IndexedAccessType).objectType;
2532725334 }
2532825335 while (type.flags & TypeFlags.IndexedAccess);
2532925336 return type;
2533025337 }
25331- if (type.flags & TypeFlags.Conditional) {
25338+ else if (type.flags & TypeFlags.Conditional) {
2533225339 // The root object represents the origin of the conditional type
2533325340 return (type as ConditionalType).root;
2533425341 }
0 commit comments