@@ -6632,11 +6632,30 @@ namespace ts {
6632
6632
}
6633
6633
6634
6634
function getErasedSignature(signature: Signature): Signature {
6635
- if (!signature.typeParameters) return signature;
6636
- if (!signature.erasedSignatureCache) {
6637
- signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
6638
- }
6639
- return signature.erasedSignatureCache;
6635
+ return signature.typeParameters ?
6636
+ signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
6637
+ signature;
6638
+ }
6639
+
6640
+ function createErasedSignature(signature: Signature) {
6641
+ // Create an instantiation of the signature where all type arguments are the any type.
6642
+ return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
6643
+ }
6644
+
6645
+ function getCanonicalSignature(signature: Signature): Signature {
6646
+ return signature.typeParameters ?
6647
+ signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
6648
+ signature;
6649
+ }
6650
+
6651
+ function createCanonicalSignature(signature: Signature) {
6652
+ // Create an instantiation of the signature where each unconstrained type parameter is replaced with
6653
+ // its original. When a generic class or interface is instantiated, each generic method in the class or
6654
+ // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
6655
+ // where different generations of the same type parameter are in scope). This leads to a lot of new type
6656
+ // identities, and potentially a lot of work comparing those identities, so here we create an instantiation
6657
+ // that uses the original type identities for all unconstrained type parameters.
6658
+ return getSignatureInstantiation(signature, map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp));
6640
6659
}
6641
6660
6642
6661
function getOrCreateTypeFromSignature(signature: Signature): ObjectType {
@@ -8473,7 +8492,8 @@ namespace ts {
8473
8492
return Ternary.False;
8474
8493
}
8475
8494
8476
- if (source.typeParameters) {
8495
+ if (source.typeParameters && source.typeParameters !== target.typeParameters) {
8496
+ target = getCanonicalSignature(target);
8477
8497
source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes);
8478
8498
}
8479
8499
0 commit comments