@@ -5621,7 +5621,7 @@ module ts {
5621
5621
}
5622
5622
5623
5623
var isConstEnum = isConstEnumObjectType(objectType);
5624
- if (isConstEnum &&
5624
+ if (isConstEnum &&
5625
5625
(!node.argumentExpression || node.argumentExpression.kind !== SyntaxKind.StringLiteral)) {
5626
5626
error(node.argumentExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
5627
5627
return unknownType;
@@ -5653,10 +5653,10 @@ module ts {
5653
5653
}
5654
5654
5655
5655
// Check for compatible indexer types.
5656
- if (indexType.flags & ( TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike) || isTypeAssignableTo(indexType, stringOrNumberType )) {
5656
+ if (isTypeOfKind( indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike)) {
5657
5657
5658
5658
// Try to use a number indexer.
5659
- if (indexType.flags & ( TypeFlags.Any | TypeFlags.NumberLike) || isTypeAssignableTo(indexType, numberType )) {
5659
+ if (isTypeOfKind( indexType, TypeFlags.Any | TypeFlags.NumberLike)) {
5660
5660
var numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number);
5661
5661
if (numberIndexType) {
5662
5662
return numberIndexType;
@@ -6557,7 +6557,7 @@ module ts {
6557
6557
}
6558
6558
6559
6559
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
6560
- if (!(type.flags & ( TypeFlags.Any | TypeFlags.NumberLike) )) {
6560
+ if (!isTypeOfKind (type, TypeFlags.Any | TypeFlags.NumberLike)) {
6561
6561
error(operand, diagnostic);
6562
6562
return false;
6563
6563
}
@@ -6708,12 +6708,21 @@ module ts {
6708
6708
return numberType;
6709
6709
}
6710
6710
6711
- // Return true if type an object type, a type parameter, or a union type composed of only those kinds of types
6712
- function isStructuredType(type: Type): boolean {
6711
+ // Return true if type has the given flags, or is a union type composed of types that all have those flags
6712
+ function isTypeOfKind(type: Type, kind: TypeFlags): boolean {
6713
+ if (type.flags & kind) {
6714
+ return true;
6715
+ }
6713
6716
if (type.flags & TypeFlags.Union) {
6714
- return !forEach((<UnionType>type).types, t => !isStructuredType(t));
6717
+ var types = (<UnionType>type).types;
6718
+ for (var i = 0; i < types.length; i++) {
6719
+ if (!(types[i].flags & kind)) {
6720
+ return false;
6721
+ }
6722
+ }
6723
+ return true;
6715
6724
}
6716
- return (type.flags & (TypeFlags.ObjectType | TypeFlags.TypeParameter)) !== 0 ;
6725
+ return false ;
6717
6726
}
6718
6727
6719
6728
function isConstEnumObjectType(type: Type): boolean {
@@ -6730,7 +6739,7 @@ module ts {
6730
6739
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
6731
6740
// The result is always of the Boolean primitive type.
6732
6741
// NOTE: do not raise error if leftType is unknown as related error was already reported
6733
- if (!(leftType.flags & TypeFlags.Any || isStructuredType(leftType) )) {
6742
+ if (!isTypeOfKind (leftType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter )) {
6734
6743
error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
6735
6744
}
6736
6745
// NOTE: do not raise error if right is unknown as related error was already reported
@@ -6745,10 +6754,10 @@ module ts {
6745
6754
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
6746
6755
// and the right operand to be of type Any, an object type, or a type parameter type.
6747
6756
// The result is always of the Boolean primitive type.
6748
- if (leftType !== anyType && leftType !== stringType && leftType !== numberType ) {
6757
+ if (!isTypeOfKind( leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike) ) {
6749
6758
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number);
6750
6759
}
6751
- if (!(rightType.flags & TypeFlags.Any || isStructuredType(rightType) )) {
6760
+ if (!isTypeOfKind (rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter )) {
6752
6761
error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
6753
6762
}
6754
6763
return booleanType;
@@ -6909,16 +6918,16 @@ module ts {
6909
6918
if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType;
6910
6919
6911
6920
var resultType: Type;
6912
- if (leftType.flags & TypeFlags.NumberLike && rightType.flags & TypeFlags.NumberLike) {
6921
+ if (isTypeOfKind( leftType, TypeFlags.NumberLike) && isTypeOfKind( rightType, TypeFlags.NumberLike) ) {
6913
6922
// Operands of an enum type are treated as having the primitive type Number.
6914
6923
// If both operands are of the Number primitive type, the result is of the Number primitive type.
6915
6924
resultType = numberType;
6916
6925
}
6917
- else if (leftType.flags & TypeFlags.StringLike || rightType.flags & TypeFlags.StringLike) {
6926
+ else if (isTypeOfKind( leftType, TypeFlags.StringLike) || isTypeOfKind( rightType, TypeFlags.StringLike) ) {
6918
6927
// If one or both operands are of the String primitive type, the result is of the String primitive type.
6919
6928
resultType = stringType;
6920
6929
}
6921
- else if (leftType.flags & TypeFlags.Any || leftType === unknownType || rightType.flags & TypeFlags.Any || rightType === unknownType ) {
6930
+ else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) {
6922
6931
// Otherwise, the result is of type Any.
6923
6932
// NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
6924
6933
resultType = anyType;
@@ -8274,7 +8283,7 @@ module ts {
8274
8283
var exprType = checkExpression(node.expression);
8275
8284
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
8276
8285
// in this case error about missing name is already reported - do not report extra one
8277
- if (!(exprType.flags & TypeFlags.Any || isStructuredType(exprType) )) {
8286
+ if (!isTypeOfKind (exprType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter )) {
8278
8287
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
8279
8288
}
8280
8289
0 commit comments