@@ -3610,9 +3610,9 @@ namespace ts {
36103610 setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo);
36113611 }
36123612
3613- function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreReturnTypes: boolean): Signature {
3613+ function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean): Signature {
36143614 for (const s of signatureList) {
3615- if (compareSignaturesIdentical(s, signature, partialMatch, ignoreReturnTypes, compareTypesIdentical)) {
3615+ if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypesIdentical)) {
36163616 return s;
36173617 }
36183618 }
@@ -3626,7 +3626,7 @@ namespace ts {
36263626 return undefined;
36273627 }
36283628 for (let i = 1; i < signatureLists.length; i++) {
3629- if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ false)) {
3629+ if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /* ignoreReturnTypes*/ false)) {
36303630 return undefined;
36313631 }
36323632 }
@@ -3635,7 +3635,7 @@ namespace ts {
36353635 let result: Signature[] = undefined;
36363636 for (let i = 0; i < signatureLists.length; i++) {
36373637 // Allow matching non-generic signatures to have excess parameters and different return types
3638- const match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreReturnTypes*/ true);
3638+ const match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /* ignoreReturnTypes*/ true);
36393639 if (!match) {
36403640 return undefined;
36413641 }
@@ -3656,13 +3656,16 @@ namespace ts {
36563656 for (let i = 0; i < signatureLists.length; i++) {
36573657 for (const signature of signatureLists[i]) {
36583658 // Only process signatures with parameter lists that aren't already in the result list
3659- if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true)) {
3659+ if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /* ignoreReturnTypes*/ true)) {
36603660 const unionSignatures = findMatchingSignatures(signatureLists, signature, i);
36613661 if (unionSignatures) {
36623662 let s = signature;
36633663 // Union the result types when more than one signature matches
36643664 if (unionSignatures.length > 1) {
36653665 s = cloneSignature(signature);
3666+ if (forEach(unionSignatures, sig => sig.thisType)) {
3667+ s.thisType = getUnionType(map(unionSignatures, sig => sig.thisType || anyType));
3668+ }
36663669 // Clear resolved return type we possibly got from cloneSignature
36673670 s.resolvedReturnType = undefined;
36683671 s.unionSignatures = unionSignatures;
@@ -6002,7 +6005,7 @@ namespace ts {
60026005 }
60036006 let result = Ternary.True;
60046007 for (let i = 0, len = sourceSignatures.length; i < len; i++) {
6005- const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
6008+ const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /* ignoreReturnTypes*/ false, isRelatedTo);
60066009 if (!related) {
60076010 return Ternary.False;
60086011 }
@@ -6203,7 +6206,7 @@ namespace ts {
62036206 /**
62046207 * See signatureRelatedTo, compareSignaturesIdentical
62056208 */
6206- function compareSignaturesIdentical(source: Signature, target: Signature, partialMatch: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
6209+ function compareSignaturesIdentical(source: Signature, target: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
62076210 // TODO (drosen): De-duplicate code between related functions.
62086211 if (source === target) {
62096212 return Ternary.True;
@@ -6224,6 +6227,13 @@ namespace ts {
62246227 source = getErasedSignature(source);
62256228 target = getErasedSignature(target);
62266229 let result = Ternary.True;
6230+ if (!ignoreThisTypes && source.thisType && target.thisType) {
6231+ const related = compareTypes(source.thisType, target.thisType);
6232+ if (!related) {
6233+ return Ternary.False;
6234+ }
6235+ result &= related;
6236+ }
62276237 const targetLen = target.parameters.length;
62286238 for (let i = 0; i < targetLen; i++) {
62296239 const s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
@@ -8137,7 +8147,7 @@ namespace ts {
81378147 // This signature will contribute to contextual union signature
81388148 signatureList = [signature];
81398149 }
8140- else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
8150+ else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /* ignoreReturnTypes*/ true, compareTypesIdentical)) {
81418151 // Signatures aren't identical, do not use
81428152 return undefined;
81438153 }
0 commit comments