Skip to content

Commit 71d535a

Browse files
committed
Fix 61429: Update arithmetic to use maybeTypeOfKindConsideringBaseConstraint
1 parent f33a6a6 commit 71d535a

File tree

1 file changed

+39
-34
lines changed

1 file changed

+39
-34
lines changed

src/compiler/checker.ts

+39-34
Original file line numberDiff line numberDiff line change
@@ -39252,7 +39252,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3925239252
}
3925339253
return numberType;
3925439254
}
39255-
return getUnaryResultType(operandType);
39255+
return getUnaryArithmeticResultType(operandType);
3925639256
case SyntaxKind.ExclamationToken:
3925739257
checkTruthinessOfType(operandType, node.operand);
3925839258
const facts = getTypeFacts(operandType, TypeFacts.Truthy | TypeFacts.Falsy);
@@ -39270,7 +39270,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3927039270
Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access,
3927139271
);
3927239272
}
39273-
return getUnaryResultType(operandType);
39273+
return getUnaryArithmeticResultType(operandType);
3927439274
}
3927539275
return errorType;
3927639276
}
@@ -39293,11 +39293,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3929339293
Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access,
3929439294
);
3929539295
}
39296-
return getUnaryResultType(operandType);
39296+
return getUnaryArithmeticResultType(operandType);
3929739297
}
3929839298

39299-
function getUnaryResultType(operandType: Type): Type {
39300-
if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) {
39299+
function getUnaryArithmeticResultType(operandType: Type): Type {
39300+
if (maybeTypeOfKindConsideringBaseConstraint(operandType, TypeFlags.BigIntLike)) {
3930139301
return isTypeAssignableToKind(operandType, TypeFlags.AnyOrUnknown) || maybeTypeOfKind(operandType, TypeFlags.NumberLike)
3930239302
? numberOrBigIntType
3930339303
: bigintType;
@@ -40009,35 +40009,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4000940009
// otherwise just check each operand separately and report errors as normal
4001040010
const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true);
4001140011
const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true);
40012-
let resultType: Type;
40013-
// If both are any or unknown, allow operation; assume it will resolve to number
40014-
if (
40015-
(isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) ||
40016-
// Or, if neither could be bigint, implicit coercion results in a number result
40017-
!(maybeTypeOfKind(leftType, TypeFlags.BigIntLike) || maybeTypeOfKind(rightType, TypeFlags.BigIntLike))
40018-
) {
40019-
resultType = numberType;
40020-
}
40021-
// At least one is assignable to bigint, so check that both are
40022-
else if (bothAreBigIntLike(leftType, rightType)) {
40023-
switch (operator) {
40024-
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
40025-
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
40026-
reportOperatorError();
40027-
break;
40028-
case SyntaxKind.AsteriskAsteriskToken:
40029-
case SyntaxKind.AsteriskAsteriskEqualsToken:
40030-
if (languageVersion < ScriptTarget.ES2016) {
40031-
error(errorNode, Diagnostics.Exponentiation_cannot_be_performed_on_bigint_values_unless_the_target_option_is_set_to_es2016_or_later);
40032-
}
40033-
}
40034-
resultType = bigintType;
40035-
}
40036-
// Exactly one of leftType/rightType is assignable to bigint
40037-
else {
40038-
reportOperatorError(bothAreBigIntLike);
40039-
resultType = errorType;
40040-
}
40012+
40013+
const resultType = getBinaryArithmeticResultType(leftType, rightType);
4004140014
if (leftOk && rightOk) {
4004240015
checkAssignmentOperator(resultType);
4004340016
switch (operator) {
@@ -40228,6 +40201,38 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4022840201
return Debug.fail();
4022940202
}
4023040203

40204+
function getBinaryArithmeticResultType(leftType: Type, rightType: Type): Type {
40205+
if (isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) {
40206+
// If both are any or unknown, allow operation; assume it will resolve to number
40207+
// (This is unsound, but it is not practical for untyped programs to
40208+
// have `bigint|number` inferred everywhere; #41741)
40209+
return numberType;
40210+
}
40211+
else if (!maybeTypeOfKindConsideringBaseConstraint(leftType, TypeFlags.BigIntLike) && !maybeTypeOfKindConsideringBaseConstraint(rightType, TypeFlags.BigIntLike)) {
40212+
// If neither could be bigint, implicit coercion results in a number result
40213+
return numberType;
40214+
}
40215+
// At least one is assignable to bigint, so check that both are
40216+
else if (bothAreBigIntLike(leftType, rightType)) {
40217+
switch (operator) {
40218+
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
40219+
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
40220+
reportOperatorError();
40221+
break;
40222+
case SyntaxKind.AsteriskAsteriskToken:
40223+
case SyntaxKind.AsteriskAsteriskEqualsToken:
40224+
if (languageVersion < ScriptTarget.ES2016) {
40225+
error(errorNode, Diagnostics.Exponentiation_cannot_be_performed_on_bigint_values_unless_the_target_option_is_set_to_es2016_or_later);
40226+
}
40227+
}
40228+
return bigintType;
40229+
}
40230+
40231+
// Exactly one of leftType/rightType is assignable to bigint
40232+
reportOperatorError(bothAreBigIntLike);
40233+
return errorType;
40234+
}
40235+
4023140236
function bothAreBigIntLike(left: Type, right: Type): boolean {
4023240237
return isTypeAssignableToKind(left, TypeFlags.BigIntLike) && isTypeAssignableToKind(right, TypeFlags.BigIntLike);
4023340238
}

0 commit comments

Comments
 (0)