@@ -7556,11 +7556,11 @@ namespace ts {
75567556 return getTypeOfSymbol(prop);
75577557 }
75587558 }
7559- if (isTypeAnyOrAllConstituentTypesHaveKind (indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
7559+ if (!(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind (indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
75607560 if (isTypeAny(objectType)) {
75617561 return anyType;
75627562 }
7563- const indexInfo = isTypeAnyOrAllConstituentTypesHaveKind (indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
7563+ const indexInfo = isTypeAssignableToKind (indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) ||
75647564 getIndexInfoOfType(objectType, IndexKind.String) ||
75657565 undefined;
75667566 if (indexInfo) {
@@ -11384,7 +11384,7 @@ namespace ts {
1138411384 (<BinaryExpression>parent.parent).operatorToken.kind === SyntaxKind.EqualsToken &&
1138511385 (<BinaryExpression>parent.parent).left === parent &&
1138611386 !isAssignmentTarget(parent.parent) &&
11387- isTypeAnyOrAllConstituentTypesHaveKind (getTypeOfExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined );
11387+ isTypeAssignableToKind (getTypeOfExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike);
1138811388 return isLengthPushOrUnshift || isElementAssignment;
1138911389 }
1139011390
@@ -11556,7 +11556,7 @@ namespace ts {
1155611556 }
1155711557 else {
1155811558 const indexType = getTypeOfExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
11559- if (isTypeAnyOrAllConstituentTypesHaveKind (indexType, TypeFlags.NumberLike | TypeFlags.Undefined )) {
11559+ if (isTypeAssignableToKind (indexType, TypeFlags.NumberLike)) {
1156011560 evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
1156111561 }
1156211562 }
@@ -13398,11 +13398,7 @@ namespace ts {
1339813398 function isNumericComputedName(name: ComputedPropertyName): boolean {
1339913399 // It seems odd to consider an expression of type Any to result in a numeric name,
1340013400 // but this behavior is consistent with checkIndexedAccess
13401- return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), TypeFlags.NumberLike);
13402- }
13403-
13404- function isTypeAnyOrAllConstituentTypesHaveKind(type: Type, kind: TypeFlags): boolean {
13405- return isTypeAny(type) || isTypeOfKind(type, kind);
13401+ return isTypeAssignableToKind(checkComputedPropertyName(name), TypeFlags.NumberLike);
1340613402 }
1340713403
1340813404 function isInfinityOrNaNString(name: string | __String): boolean {
@@ -13438,10 +13434,11 @@ namespace ts {
1343813434 const links = getNodeLinks(node.expression);
1343913435 if (!links.resolvedType) {
1344013436 links.resolvedType = checkExpression(node.expression);
13441-
1344213437 // This will allow types number, string, symbol or any. It will also allow enums, the unknown
1344313438 // type, and any union of these types (like string | number).
13444- if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) {
13439+ if (links.resolvedType.flags & TypeFlags.Nullable ||
13440+ !isTypeAssignableToKind(links.resolvedType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol) &&
13441+ !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) {
1344513442 error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
1344613443 }
1344713444 else {
@@ -15546,7 +15543,7 @@ namespace ts {
1554615543
1554715544 case SyntaxKind.ComputedPropertyName:
1554815545 const nameType = checkComputedPropertyName(element.name);
15549- if (isTypeOfKind (nameType, TypeFlags.ESSymbol)) {
15546+ if (isTypeAssignableToKind (nameType, TypeFlags.ESSymbol)) {
1555015547 return nameType;
1555115548 }
1555215549 else {
@@ -16936,7 +16933,7 @@ namespace ts {
1693616933 }
1693716934
1693816935 function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
16939- if (!isTypeAnyOrAllConstituentTypesHaveKind (type, TypeFlags.NumberLike)) {
16936+ if (!isTypeAssignableToKind (type, TypeFlags.NumberLike)) {
1694016937 error(operand, diagnostic);
1694116938 return false;
1694216939 }
@@ -17114,31 +17111,22 @@ namespace ts {
1711417111 return false;
1711517112 }
1711617113
17117- // Return true if type is of the given kind. A union type is of a given kind if all constituent types
17118- // are of the given kind. An intersection type is of a given kind if at least one constituent type is
17119- // of the given kind.
17120- function isTypeOfKind(type: Type, kind: TypeFlags): boolean {
17121- if (type.flags & kind) {
17114+ function isTypeAssignableToKind(source: Type, kind: TypeFlags, strict?: boolean): boolean {
17115+ if (source.flags & kind) {
1712217116 return true;
1712317117 }
17124- if (type.flags & TypeFlags.Union) {
17125- const types = (<UnionOrIntersectionType>type).types;
17126- for (const t of types) {
17127- if (!isTypeOfKind(t, kind)) {
17128- return false;
17129- }
17130- }
17131- return true;
17132- }
17133- if (type.flags & TypeFlags.Intersection) {
17134- const types = (<UnionOrIntersectionType>type).types;
17135- for (const t of types) {
17136- if (isTypeOfKind(t, kind)) {
17137- return true;
17138- }
17139- }
17118+ if (strict && source.flags & (TypeFlags.Any | TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null)) {
17119+ return false;
1714017120 }
17141- return false;
17121+ return (kind & TypeFlags.NumberLike && isTypeAssignableTo(source, numberType)) ||
17122+ (kind & TypeFlags.StringLike && isTypeAssignableTo(source, stringType)) ||
17123+ (kind & TypeFlags.BooleanLike && isTypeAssignableTo(source, booleanType)) ||
17124+ (kind & TypeFlags.Void && isTypeAssignableTo(source, voidType)) ||
17125+ (kind & TypeFlags.Never && isTypeAssignableTo(source, neverType)) ||
17126+ (kind & TypeFlags.Null && isTypeAssignableTo(source, nullType)) ||
17127+ (kind & TypeFlags.Undefined && isTypeAssignableTo(source, undefinedType)) ||
17128+ (kind & TypeFlags.ESSymbol && isTypeAssignableTo(source, esSymbolType)) ||
17129+ (kind & TypeFlags.NonPrimitive && isTypeAssignableTo(source, nonPrimitiveType));
1714217130 }
1714317131
1714417132 function isConstEnumObjectType(type: Type): boolean {
@@ -17158,7 +17146,7 @@ namespace ts {
1715817146 // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature.
1715917147 // The result is always of the Boolean primitive type.
1716017148 // NOTE: do not raise error if leftType is unknown as related error was already reported
17161- if (isTypeOfKind (leftType, TypeFlags.Primitive)) {
17149+ if (!isTypeAny(leftType) && isTypeAssignableToKind (leftType, TypeFlags.Primitive)) {
1716217150 error(left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
1716317151 }
1716417152 // NOTE: do not raise error if right is unknown as related error was already reported
@@ -17181,10 +17169,10 @@ namespace ts {
1718117169 // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
1718217170 // and the right operand to be of type Any, an object type, or a type parameter type.
1718317171 // The result is always of the Boolean primitive type.
17184- if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind (leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
17172+ if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind (leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) {
1718517173 error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
1718617174 }
17187- if (!isTypeAnyOrAllConstituentTypesHaveKind (rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive )) {
17175+ if (!isTypeAssignableToKind (rightType, TypeFlags.NonPrimitive | TypeFlags.TypeVariable)) {
1718817176 error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
1718917177 }
1719017178 return booleanType;
@@ -17493,32 +17481,30 @@ namespace ts {
1749317481 return silentNeverType;
1749417482 }
1749517483
17496- if (!isTypeOfKind (leftType, TypeFlags.Any | TypeFlags. StringLike) && !isTypeOfKind (rightType, TypeFlags.Any | TypeFlags.StringLike)) {
17484+ if (!isTypeAssignableToKind (leftType, TypeFlags.StringLike) && !isTypeAssignableToKind (rightType, TypeFlags.StringLike)) {
1749717485 leftType = checkNonNullType(leftType, left);
1749817486 rightType = checkNonNullType(rightType, right);
1749917487 }
1750017488
1750117489 let resultType: Type;
17502- if (isTypeOfKind (leftType, TypeFlags.NumberLike) && isTypeOfKind (rightType, TypeFlags.NumberLike)) {
17490+ if (isTypeAssignableToKind (leftType, TypeFlags.NumberLike, /*strict*/ true ) && isTypeAssignableToKind (rightType, TypeFlags.NumberLike, /*strict*/ true )) {
1750317491 // Operands of an enum type are treated as having the primitive type Number.
1750417492 // If both operands are of the Number primitive type, the result is of the Number primitive type.
1750517493 resultType = numberType;
1750617494 }
17507- else {
17508- if (isTypeOfKind(leftType, TypeFlags.StringLike) || isTypeOfKind(rightType, TypeFlags.StringLike)) {
17495+ else if (isTypeAssignableToKind(leftType, TypeFlags.StringLike, /*strict*/ true) || isTypeAssignableToKind(rightType, TypeFlags.StringLike, /*strict*/ true)) {
1750917496 // If one or both operands are of the String primitive type, the result is of the String primitive type.
1751017497 resultType = stringType;
17511- }
17512- else if (isTypeAny(leftType) || isTypeAny(rightType)) {
17513- // Otherwise, the result is of type Any.
17514- // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
17515- resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType;
17516- }
17498+ }
17499+ else if (isTypeAny(leftType) || isTypeAny(rightType)) {
17500+ // Otherwise, the result is of type Any.
17501+ // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
17502+ resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType;
17503+ }
1751717504
17518- // Symbols are not allowed at all in arithmetic expressions
17519- if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
17520- return resultType;
17521- }
17505+ // Symbols are not allowed at all in arithmetic expressions
17506+ if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
17507+ return resultType;
1752217508 }
1752317509
1752417510 if (!resultType) {
@@ -18732,7 +18718,7 @@ namespace ts {
1873218718 }
1873318719 // Check if we're indexing with a numeric type and the object type is a generic
1873418720 // type with a constraint that has a numeric index signature.
18735- if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeOfKind (indexType, TypeFlags.NumberLike)) {
18721+ if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeAssignableToKind (indexType, TypeFlags.NumberLike)) {
1873618722 const constraint = getBaseConstraintOfType(objectType);
1873718723 if (constraint && getIndexInfoOfType(constraint, IndexKind.Number)) {
1873818724 return type;
@@ -20439,7 +20425,7 @@ namespace ts {
2043920425
2044020426 // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
2044120427 // in this case error about missing name is already reported - do not report extra one
20442- if (!isTypeAnyOrAllConstituentTypesHaveKind (rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive )) {
20428+ if (!isTypeAssignableToKind (rightType, TypeFlags.NonPrimitive | TypeFlags.TypeVariable)) {
2044320429 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);
2044420430 }
2044520431
@@ -23426,22 +23412,22 @@ namespace ts {
2342623412 else if (type.flags & TypeFlags.Any) {
2342723413 return TypeReferenceSerializationKind.ObjectType;
2342823414 }
23429- else if (isTypeOfKind (type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never)) {
23415+ else if (isTypeAssignableToKind (type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never)) {
2343023416 return TypeReferenceSerializationKind.VoidNullableOrNeverType;
2343123417 }
23432- else if (isTypeOfKind (type, TypeFlags.BooleanLike)) {
23418+ else if (isTypeAssignableToKind (type, TypeFlags.BooleanLike)) {
2343323419 return TypeReferenceSerializationKind.BooleanType;
2343423420 }
23435- else if (isTypeOfKind (type, TypeFlags.NumberLike)) {
23421+ else if (isTypeAssignableToKind (type, TypeFlags.NumberLike)) {
2343623422 return TypeReferenceSerializationKind.NumberLikeType;
2343723423 }
23438- else if (isTypeOfKind (type, TypeFlags.StringLike)) {
23424+ else if (isTypeAssignableToKind (type, TypeFlags.StringLike)) {
2343923425 return TypeReferenceSerializationKind.StringLikeType;
2344023426 }
2344123427 else if (isTupleType(type)) {
2344223428 return TypeReferenceSerializationKind.ArrayLikeType;
2344323429 }
23444- else if (isTypeOfKind (type, TypeFlags.ESSymbol)) {
23430+ else if (isTypeAssignableToKind (type, TypeFlags.ESSymbol)) {
2344523431 return TypeReferenceSerializationKind.ESSymbolType;
2344623432 }
2344723433 else if (isFunctionType(type)) {
0 commit comments