Merge pull request #10069 from Microsoft/bestChoiceType

Use "best choice type" for || and ?: operators
This commit is contained in:
Anders Hejlsberg
2016-08-01 15:26:57 -07:00
committed by GitHub
9 changed files with 223 additions and 10 deletions

View File

@@ -12903,6 +12903,14 @@ namespace ts {
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
}
function getBestChoiceType(type1: Type, type2: Type): Type {
const firstAssignableToSecond = isTypeAssignableTo(type1, type2);
const secondAssignableToFirst = isTypeAssignableTo(type2, type1);
return secondAssignableToFirst && !firstAssignableToSecond ? type1 :
firstAssignableToSecond && !secondAssignableToFirst ? type2 :
getUnionType([type1, type2], /*subtypeReduction*/ true);
}
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
}
@@ -13046,7 +13054,7 @@ namespace ts {
leftType;
case SyntaxKind.BarBarToken:
return getTypeFacts(leftType) & TypeFacts.Falsy ?
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) :
getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) :
leftType;
case SyntaxKind.EqualsToken:
checkAssignmentOperator(rightType);
@@ -13173,7 +13181,7 @@ namespace ts {
checkExpression(node.condition);
const type1 = checkExpression(node.whenTrue, contextualMapper);
const type2 = checkExpression(node.whenFalse, contextualMapper);
return getUnionType([type1, type2], /*subtypeReduction*/ true);
return getBestChoiceType(type1, type2);
}
function typeContainsLiteralFromEnum(type: Type, enumType: EnumType) {