mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-18 07:29:16 -05:00
Merge pull request #32904 from microsoft/getRidOfCrappyLiterals
Prefer reporting base primitives in various operations
This commit is contained in:
@@ -24086,7 +24086,7 @@ namespace ts {
|
||||
}
|
||||
if (node.operator === SyntaxKind.PlusToken) {
|
||||
if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) {
|
||||
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(operandType));
|
||||
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType)));
|
||||
}
|
||||
return numberType;
|
||||
}
|
||||
@@ -24521,7 +24521,7 @@ namespace ts {
|
||||
resultType = numberType;
|
||||
}
|
||||
// At least one is assignable to bigint, so check that both are
|
||||
else if (isTypeAssignableToKind(leftType, TypeFlags.BigIntLike) && isTypeAssignableToKind(rightType, TypeFlags.BigIntLike)) {
|
||||
else if (bothAreBigIntLike(leftType, rightType)) {
|
||||
switch (operator) {
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
|
||||
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
|
||||
@@ -24531,7 +24531,7 @@ namespace ts {
|
||||
}
|
||||
// Exactly one of leftType/rightType is assignable to bigint
|
||||
else {
|
||||
reportOperatorError((awaitedLeft, awaitedRight) => isTypeAssignableToKind(awaitedLeft, TypeFlags.BigIntLike) && isTypeAssignableToKind(awaitedRight, TypeFlags.BigIntLike));
|
||||
reportOperatorError(bothAreBigIntLike);
|
||||
resultType = errorType;
|
||||
}
|
||||
if (leftOk && rightOk) {
|
||||
@@ -24581,9 +24581,9 @@ namespace ts {
|
||||
// might be missing an await without doing an exhaustive check that inserting
|
||||
// await(s) will actually be a completely valid binary expression.
|
||||
const closeEnoughKind = TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.AnyOrUnknown;
|
||||
reportOperatorError((awaitedLeft, awaitedRight) =>
|
||||
isTypeAssignableToKind(awaitedLeft, closeEnoughKind) &&
|
||||
isTypeAssignableToKind(awaitedRight, closeEnoughKind));
|
||||
reportOperatorError((left, right) =>
|
||||
isTypeAssignableToKind(left, closeEnoughKind) &&
|
||||
isTypeAssignableToKind(right, closeEnoughKind));
|
||||
return anyType;
|
||||
}
|
||||
|
||||
@@ -24651,6 +24651,10 @@ namespace ts {
|
||||
return Debug.fail();
|
||||
}
|
||||
|
||||
function bothAreBigIntLike(left: Type, right: Type): boolean {
|
||||
return isTypeAssignableToKind(left, TypeFlags.BigIntLike) && isTypeAssignableToKind(right, TypeFlags.BigIntLike);
|
||||
}
|
||||
|
||||
function checkAssignmentDeclaration(kind: AssignmentDeclarationKind, rightType: Type) {
|
||||
if (kind === AssignmentDeclarationKind.ModuleExports) {
|
||||
for (const prop of getPropertiesOfObjectType(rightType)) {
|
||||
@@ -24747,18 +24751,23 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function reportOperatorError(awaitedTypesAreCompatible?: (left: Type, right: Type) => boolean) {
|
||||
function reportOperatorError(isRelated?: (left: Type, right: Type) => boolean) {
|
||||
let wouldWorkWithAwait = false;
|
||||
const errNode = errorNode || operatorToken;
|
||||
const [leftStr, rightStr] = getTypeNamesForErrorDisplay(leftType, rightType);
|
||||
if (awaitedTypesAreCompatible) {
|
||||
if (isRelated) {
|
||||
const awaitedLeftType = getAwaitedType(leftType);
|
||||
const awaitedRightType = getAwaitedType(rightType);
|
||||
wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType)
|
||||
&& !!(awaitedLeftType && awaitedRightType)
|
||||
&& awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType);
|
||||
&& isRelated(awaitedLeftType, awaitedRightType);
|
||||
}
|
||||
|
||||
let effectiveLeft = leftType;
|
||||
let effectiveRight = rightType;
|
||||
if (!wouldWorkWithAwait && isRelated) {
|
||||
[effectiveLeft, effectiveRight] = getBaseTypesIfUnrelated(leftType, rightType, isRelated);
|
||||
}
|
||||
const [leftStr, rightStr] = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight);
|
||||
if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) {
|
||||
errorAndMaybeSuggestAwait(
|
||||
errNode,
|
||||
@@ -24795,6 +24804,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getBaseTypesIfUnrelated(leftType: Type, rightType: Type, isRelated: (left: Type, right: Type) => boolean): [Type, Type] {
|
||||
let effectiveLeft = leftType;
|
||||
let effectiveRight = rightType;
|
||||
const leftBase = getBaseTypeOfLiteralType(leftType);
|
||||
const rightBase = getBaseTypeOfLiteralType(rightType);
|
||||
if (!isRelated(leftBase, rightBase)) {
|
||||
effectiveLeft = leftBase;
|
||||
effectiveRight = rightBase;
|
||||
}
|
||||
return [ effectiveLeft, effectiveRight ];
|
||||
}
|
||||
|
||||
function isYieldExpressionInClass(node: YieldExpression): boolean {
|
||||
let current: Node = node;
|
||||
let parent = node.parent;
|
||||
|
||||
Reference in New Issue
Block a user