Skip to content

Commit ea0a6de

Browse files
committed
Compare type parameters, constraints, and defaults in signature identity
1 parent be4147d commit ea0a6de

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

src/compiler/checker.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -14322,20 +14322,25 @@ namespace ts {
1432214322
if (!(isMatchingSignature(source, target, partialMatch))) {
1432314323
return Ternary.False;
1432414324
}
14325-
// Check that the two signatures have the same number of type parameters. We might consider
14326-
// also checking that any type parameter constraints match, but that would require instantiating
14327-
// the constraints with a common set of type arguments to get relatable entities in places where
14328-
// type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
14329-
// particularly as we're comparing erased versions of the signatures below.
14325+
// Check that the two signatures have the same number of type parameters.
1433014326
if (length(source.typeParameters) !== length(target.typeParameters)) {
1433114327
return Ternary.False;
1433214328
}
14333-
// Spec 1.0 Section 3.8.3 & 3.8.4:
14334-
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
14335-
source = getErasedSignature(source);
14336-
target = getErasedSignature(target);
14329+
// Check that type parameter constraints and defaults match. If they do, instantiate the source
14330+
// signature with the type parameters of the target signature and continue the comparison.
14331+
if (target.typeParameters) {
14332+
const mapper = createTypeMapper(source.typeParameters!, target.typeParameters);
14333+
for (let i = 0; i < target.typeParameters.length; i++) {
14334+
const s = source.typeParameters![i];
14335+
const t = target.typeParameters[i];
14336+
if (!(s === t || compareTypes(instantiateType(getConstraintFromTypeParameter(s), mapper) || unknownType, getConstraintFromTypeParameter(t) || unknownType) &&
14337+
compareTypes(instantiateType(getDefaultFromTypeParameter(s), mapper) || unknownType, getDefaultFromTypeParameter(t) || unknownType))) {
14338+
return Ternary.False;
14339+
}
14340+
}
14341+
source = instantiateSignature(source, mapper, /*eraseTypeParameters*/ true);
14342+
}
1433714343
let result = Ternary.True;
14338-
1433914344
if (!ignoreThisTypes) {
1434014345
const sourceThisType = getThisTypeOfSignature(source);
1434114346
if (sourceThisType) {
@@ -14349,7 +14354,6 @@ namespace ts {
1434914354
}
1435014355
}
1435114356
}
14352-
1435314357
const targetLen = getParameterCount(target);
1435414358
for (let i = 0; i < targetLen; i++) {
1435514359
const s = getTypeAtPosition(source, i);

0 commit comments

Comments
 (0)