Skip to content

Commit

Permalink
Revert "Check callback return values bi-variantly"
Browse files Browse the repository at this point in the history
This reverts commit 189fc51.
  • Loading branch information
mhegazy committed Apr 25, 2017
1 parent d581bed commit 42d6a9c
Showing 1 changed file with 11 additions and 19 deletions.
30 changes: 11 additions & 19 deletions src/compiler/checker.ts
Expand Up @@ -8177,7 +8177,7 @@ namespace ts {
function isSignatureAssignableTo(source: Signature,
target: Signature,
ignoreReturnTypes: boolean): boolean {
return compareSignaturesRelated(source, target, /*checkAsCallback*/ false, ignoreReturnTypes, /*reportErrors*/ false,
return compareSignaturesRelated(source, target, /*strictVariance*/ false, ignoreReturnTypes, /*reportErrors*/ false,
/*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
}

Expand All @@ -8188,7 +8188,7 @@ namespace ts {
*/
function compareSignaturesRelated(source: Signature,
target: Signature,
checkAsCallback: boolean,
strictVariance: boolean,
ignoreReturnTypes: boolean,
reportErrors: boolean,
errorReporter: ErrorReporter,
Expand Down Expand Up @@ -8235,17 +8235,13 @@ namespace ts {
const targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target);
const sourceSig = getSingleCallSignature(sourceType);
const targetSig = getSingleCallSignature(targetType);
// In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
// how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
// they naturally relate only contra-variantly). However, if the source and target parameters both have
// function types with a single call signature, we known we are relating two callback parameters. In
// that case it is sufficient to only relate the parameters of the signatures co-variantly because,
// similar to return values, callback parameters are output positions. This means that a Promise<T>,
// where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
// with respect to T.
const related = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate ?
compareSignaturesRelated(targetSig, sourceSig, /*checkAsCallback*/ true, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
!checkAsCallback && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
// If the source and target parameters both have function types with a single call signature we are
// relating two callback parameters. In that case we compare the callback signatures with strict
// variance, meaning we require the callback parameters to be pairwise co-variant (because, similar
// to return values, callback parameters are output positions).
const related = sourceSig && targetSig ?
compareSignaturesRelated(targetSig, sourceSig, /*strictVariance*/ true, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
!strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
if (!related) {
if (reportErrors) {
errorReporter(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
Expand Down Expand Up @@ -8277,11 +8273,7 @@ namespace ts {
}
}
else {
// When relating callback signatures, we still need to relate return types bi-variantly as otherwise
// the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
// wouldn't be co-variant for T without this rule.
result &= checkAsCallback && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
compareTypes(sourceReturnType, targetReturnType, reportErrors);
result &= compareTypes(sourceReturnType, targetReturnType, reportErrors);
}

}
Expand Down Expand Up @@ -9249,7 +9241,7 @@ namespace ts {
* See signatureAssignableTo, compareSignaturesIdentical
*/
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
return compareSignaturesRelated(source, target, /*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
return compareSignaturesRelated(source, target, /*strictVariance*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
}

function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
Expand Down

0 comments on commit 42d6a9c

Please sign in to comment.