Skip to content

Commit 72260d4

Browse files
committed
Only track instantiated object types by their symbol
1 parent 55423ab commit 72260d4

2 files changed

Lines changed: 20 additions & 12 deletions

File tree

src/compiler/checker.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6563,6 +6563,7 @@ export const enum ObjectFlags {
65636563
IdenticalBaseTypeCalculated = 1 << 25, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already
65646564
/** @internal */
65656565
IdenticalBaseTypeExists = 1 << 26, // has a defined cachedEquivalentBaseType member
6566+
InstantiatedReference = 1 << 27, // Originates in instantiation of type reference
65666567

65676568
// Flags that require TypeFlags.UnionOrIntersection or TypeFlags.Substitution
65686569
/** @internal */

0 commit comments

Comments
 (0)