Skip to content

Commit

Permalink
Optimize variance checking during identity checking
Browse files Browse the repository at this point in the history
  • Loading branch information
weswigham committed Apr 12, 2019
1 parent e951455 commit 73ab894
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/compiler/checker.ts
Expand Up @@ -10250,15 +10250,15 @@ namespace ts {

function getConditionalTypeWorker(root: ConditionalRoot, mapper: TypeMapper | undefined, checkType: Type, extendsType: Type, trueType: Type, falseType: Type) {
// Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`.
if (falseType.flags & TypeFlags.Never && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) {
if (falseType.flags & TypeFlags.Never && isTypeIdenticalTo(getActualTypeVariable(trueType), getActualTypeVariable(checkType))) {
if (checkType.flags & TypeFlags.Any || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
return trueType;
}
else if (isIntersectionEmpty(checkType, extendsType)) { // Always false
return neverType;
}
}
else if (trueType.flags & TypeFlags.Never && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) {
else if (trueType.flags & TypeFlags.Never && isTypeIdenticalTo(getActualTypeVariable(falseType), getActualTypeVariable(checkType))) {
if (!(checkType.flags & TypeFlags.Any) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
return neverType;
}
Expand Down Expand Up @@ -12840,7 +12840,7 @@ namespace ts {
if (source.flags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol &&
source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol &&
!(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) {
const variances = getAliasVariances(source.aliasSymbol);
const variances = relation === identityRelation ? emptyArray : getAliasVariances(source.aliasSymbol);
const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances);
if (varianceResult !== undefined) {
return varianceResult;
Expand Down Expand Up @@ -13023,7 +13023,7 @@ namespace ts {
// We have type references to the same generic type, and the type references are not marker
// type references (which are intended by be compared structurally). Obtain the variance
// information for the type parameters and relate the type arguments accordingly.
const variances = getVariances((<TypeReference>source).target);
const variances = relation === identityRelation ? emptyArray : getVariances((<TypeReference>source).target);
const varianceResult = relateVariances((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, variances);
if (varianceResult !== undefined) {
return varianceResult;
Expand Down Expand Up @@ -13082,6 +13082,9 @@ namespace ts {
if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors)) {
return result;
}
if (relation === identityRelation) {
return result;
}
const allowStructuralFallback = (targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances)) || isNonGeneric(source) || isNonGeneric(target);
varianceCheckFailed = !allowStructuralFallback;
// The type arguments did not relate appropriately, but it may be because we have no variance
Expand Down

0 comments on commit 73ab894

Please sign in to comment.