@@ -2066,7 +2066,7 @@ module ts {
20662066 }
20672067
20682068 function resolveTupleTypeMembers ( type : TupleType ) {
2069- var arrayType = resolveObjectTypeMembers ( createArrayType ( getBestCommonType ( type . elementTypes ) ) ) ;
2069+ var arrayType = resolveObjectTypeMembers ( createArrayType ( getUnionType ( type . elementTypes ) ) ) ;
20702070 var members = createTupleTypeMemberSymbols ( type . elementTypes ) ;
20712071 addInheritedMembers ( members , arrayType . properties ) ;
20722072 setObjectTypeMembers ( type , members , arrayType . callSignatures , arrayType . constructSignatures , arrayType . stringIndexType , arrayType . numberIndexType ) ;
@@ -2716,13 +2716,41 @@ module ts {
27162716 }
27172717 }
27182718
2719- function getUnionType ( types : Type [ ] ) : Type {
2719+ function containsAnyType ( types : Type [ ] ) {
2720+ for ( var i = 0 ; i < types . length ; i ++ ) {
2721+ if ( types [ i ] . flags & TypeFlags . Any ) {
2722+ return true ;
2723+ }
2724+ }
2725+ return false ;
2726+ }
2727+
2728+ function removeAllButLast ( types : Type [ ] , typeToRemove : Type ) {
2729+ var i = types . length ;
2730+ while ( i > 0 && types . length > 1 ) {
2731+ i -- ;
2732+ if ( types [ i ] === typeToRemove ) {
2733+ types . splice ( i , 1 ) ;
2734+ }
2735+ }
2736+ }
2737+
2738+ function getUnionType ( types : Type [ ] , noSubtypeReduction ?: boolean ) : Type {
27202739 if ( types . length === 0 ) {
27212740 return emptyObjectType ;
27222741 }
27232742 var sortedTypes : Type [ ] = [ ] ;
27242743 addTypesToSortedSet ( sortedTypes , types ) ;
2725- removeSubtypes ( sortedTypes ) ;
2744+ if ( noSubtypeReduction ) {
2745+ if ( containsAnyType ( sortedTypes ) ) {
2746+ return anyType ;
2747+ }
2748+ removeAllButLast ( sortedTypes , undefinedType ) ;
2749+ removeAllButLast ( sortedTypes , nullType ) ;
2750+ }
2751+ else {
2752+ removeSubtypes ( sortedTypes ) ;
2753+ }
27262754 if ( sortedTypes . length === 1 ) {
27272755 return sortedTypes [ 0 ] ;
27282756 }
@@ -2738,7 +2766,7 @@ module ts {
27382766 function getTypeFromUnionTypeNode ( node : UnionTypeNode ) : Type {
27392767 var links = getNodeLinks ( node ) ;
27402768 if ( ! links . resolvedType ) {
2741- links . resolvedType = getUnionType ( map ( node . types , getTypeFromTypeNode ) ) ;
2769+ links . resolvedType = getUnionType ( map ( node . types , getTypeFromTypeNode ) , /*noSubtypeReduction*/ true ) ;
27422770 }
27432771 return links . resolvedType ;
27442772 }
@@ -2956,7 +2984,7 @@ module ts {
29562984 return createTupleType ( instantiateList ( ( < TupleType > type ) . elementTypes , mapper , instantiateType ) ) ;
29572985 }
29582986 if ( type . flags & TypeFlags . Union ) {
2959- return getUnionType ( instantiateList ( ( < UnionType > type ) . types , mapper , instantiateType ) ) ;
2987+ return getUnionType ( instantiateList ( ( < UnionType > type ) . types , mapper , instantiateType ) , /*noSubtypeReduction*/ true ) ;
29602988 }
29612989 }
29622990 return type ;
@@ -3606,7 +3634,7 @@ module ts {
36063634 return forEach ( types , t => isSupertypeOfEach ( t , types ) ? t : undefined ) ;
36073635 }
36083636
3609- function getBestCommonType ( types : Type [ ] , contextualType ? : Type ) : Type {
3637+ function getBestCommonType ( types : Type [ ] , contextualType : Type ) : Type {
36103638 return contextualType && isSupertypeOfEach ( contextualType , types ) ? contextualType : getUnionType ( types ) ; }
36113639
36123640 function isTypeOfObjectLiteral ( type : Type ) : boolean {
@@ -4558,7 +4586,7 @@ module ts {
45584586 return createTupleType ( elementTypes ) ;
45594587 }
45604588 var contextualElementType = contextualType && ! isInferentialContext ( contextualMapper ) ? getIndexTypeOfType ( contextualType , IndexKind . Number ) : undefined ;
4561- var elementType = elements . length || contextualElementType ? getBestCommonType ( deduplicate ( elementTypes ) , contextualElementType ) : undefinedType ;
4589+ var elementType = elements . length || contextualElementType ? getBestCommonType ( elementTypes , contextualElementType ) : undefinedType ;
45624590 return createArrayType ( elementType ) ;
45634591 }
45644592
@@ -5601,7 +5629,7 @@ module ts {
56015629 case SyntaxKind . AmpersandAmpersandToken :
56025630 return rightType ;
56035631 case SyntaxKind . BarBarToken :
5604- return getBestCommonType ( [ leftType , rightType ] , isInferentialContext ( contextualMapper ) ? undefined : getContextualType ( node ) ) ;
5632+ return getUnionType ( [ leftType , rightType ] ) ;
56055633 case SyntaxKind . EqualsToken :
56065634 checkAssignmentOperator ( rightType ) ;
56075635 return rightType ;
@@ -5651,9 +5679,7 @@ module ts {
56515679 checkExpression ( node . condition ) ;
56525680 var type1 = checkExpression ( node . whenTrue , contextualMapper ) ;
56535681 var type2 = checkExpression ( node . whenFalse , contextualMapper ) ;
5654- var contextualType = isInferentialContext ( contextualMapper ) ? undefined : getContextualType ( node ) ;
5655- var resultType = getBestCommonType ( [ type1 , type2 ] , contextualType ) ;
5656- return resultType ;
5682+ return getUnionType ( [ type1 , type2 ] ) ;
56575683 }
56585684
56595685 function checkExpressionWithContextualType ( node : Expression , contextualType : Type , contextualMapper ?: TypeMapper ) : Type {
0 commit comments