@@ -8177,7 +8177,7 @@ namespace ts {
8177
8177
function isSignatureAssignableTo(source: Signature,
8178
8178
target: Signature,
8179
8179
ignoreReturnTypes: boolean): boolean {
8180
- return compareSignaturesRelated(source, target, /*checkAsCallback */ false, ignoreReturnTypes, /*reportErrors*/ false,
8180
+ return compareSignaturesRelated(source, target, /*strictVariance */ false, ignoreReturnTypes, /*reportErrors*/ false,
8181
8181
/*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
8182
8182
}
8183
8183
@@ -8188,7 +8188,7 @@ namespace ts {
8188
8188
*/
8189
8189
function compareSignaturesRelated(source: Signature,
8190
8190
target: Signature,
8191
- checkAsCallback : boolean,
8191
+ strictVariance : boolean,
8192
8192
ignoreReturnTypes: boolean,
8193
8193
reportErrors: boolean,
8194
8194
errorReporter: ErrorReporter,
@@ -8235,17 +8235,13 @@ namespace ts {
8235
8235
const targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target);
8236
8236
const sourceSig = getSingleCallSignature(sourceType);
8237
8237
const targetSig = getSingleCallSignature(targetType);
8238
- // In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
8239
- // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
8240
- // they naturally relate only contra-variantly). However, if the source and target parameters both have
8241
- // function types with a single call signature, we known we are relating two callback parameters. In
8242
- // that case it is sufficient to only relate the parameters of the signatures co-variantly because,
8243
- // similar to return values, callback parameters are output positions. This means that a Promise<T>,
8244
- // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
8245
- // with respect to T.
8246
- const related = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate ?
8247
- compareSignaturesRelated(targetSig, sourceSig, /*checkAsCallback*/ true, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
8248
- !checkAsCallback && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
8238
+ // If the source and target parameters both have function types with a single call signature we are
8239
+ // relating two callback parameters. In that case we compare the callback signatures with strict
8240
+ // variance, meaning we require the callback parameters to be pairwise co-variant (because, similar
8241
+ // to return values, callback parameters are output positions).
8242
+ const related = sourceSig && targetSig ?
8243
+ compareSignaturesRelated(targetSig, sourceSig, /*strictVariance*/ true, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
8244
+ !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
8249
8245
if (!related) {
8250
8246
if (reportErrors) {
8251
8247
errorReporter(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
@@ -8277,11 +8273,7 @@ namespace ts {
8277
8273
}
8278
8274
}
8279
8275
else {
8280
- // When relating callback signatures, we still need to relate return types bi-variantly as otherwise
8281
- // the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
8282
- // wouldn't be co-variant for T without this rule.
8283
- result &= checkAsCallback && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
8284
- compareTypes(sourceReturnType, targetReturnType, reportErrors);
8276
+ result &= compareTypes(sourceReturnType, targetReturnType, reportErrors);
8285
8277
}
8286
8278
8287
8279
}
@@ -9249,7 +9241,7 @@ namespace ts {
9249
9241
* See signatureAssignableTo, compareSignaturesIdentical
9250
9242
*/
9251
9243
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
9252
- return compareSignaturesRelated(source, target, /*checkAsCallback */ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
9244
+ return compareSignaturesRelated(source, target, /*strictVariance */ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
9253
9245
}
9254
9246
9255
9247
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
0 commit comments