Skip to content

Commit d442ecc

Browse files
Merge pull request microsoft#32904 from microsoft/getRidOfCrappyLiterals
Prefer reporting base primitives in various operations
2 parents 1747ee7 + 8dec7a2 commit d442ecc

16 files changed

+201
-180
lines changed

src/compiler/checker.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24086,7 +24086,7 @@ namespace ts {
2408624086
}
2408724087
if (node.operator === SyntaxKind.PlusToken) {
2408824088
if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) {
24089-
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(operandType));
24089+
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType)));
2409024090
}
2409124091
return numberType;
2409224092
}
@@ -24521,7 +24521,7 @@ namespace ts {
2452124521
resultType = numberType;
2452224522
}
2452324523
// At least one is assignable to bigint, so check that both are
24524-
else if (isTypeAssignableToKind(leftType, TypeFlags.BigIntLike) && isTypeAssignableToKind(rightType, TypeFlags.BigIntLike)) {
24524+
else if (bothAreBigIntLike(leftType, rightType)) {
2452524525
switch (operator) {
2452624526
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
2452724527
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
@@ -24531,7 +24531,7 @@ namespace ts {
2453124531
}
2453224532
// Exactly one of leftType/rightType is assignable to bigint
2453324533
else {
24534-
reportOperatorError((awaitedLeft, awaitedRight) => isTypeAssignableToKind(awaitedLeft, TypeFlags.BigIntLike) && isTypeAssignableToKind(awaitedRight, TypeFlags.BigIntLike));
24534+
reportOperatorError(bothAreBigIntLike);
2453524535
resultType = errorType;
2453624536
}
2453724537
if (leftOk && rightOk) {
@@ -24581,9 +24581,9 @@ namespace ts {
2458124581
// might be missing an await without doing an exhaustive check that inserting
2458224582
// await(s) will actually be a completely valid binary expression.
2458324583
const closeEnoughKind = TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.AnyOrUnknown;
24584-
reportOperatorError((awaitedLeft, awaitedRight) =>
24585-
isTypeAssignableToKind(awaitedLeft, closeEnoughKind) &&
24586-
isTypeAssignableToKind(awaitedRight, closeEnoughKind));
24584+
reportOperatorError((left, right) =>
24585+
isTypeAssignableToKind(left, closeEnoughKind) &&
24586+
isTypeAssignableToKind(right, closeEnoughKind));
2458724587
return anyType;
2458824588
}
2458924589

@@ -24651,6 +24651,10 @@ namespace ts {
2465124651
return Debug.fail();
2465224652
}
2465324653

24654+
function bothAreBigIntLike(left: Type, right: Type): boolean {
24655+
return isTypeAssignableToKind(left, TypeFlags.BigIntLike) && isTypeAssignableToKind(right, TypeFlags.BigIntLike);
24656+
}
24657+
2465424658
function checkAssignmentDeclaration(kind: AssignmentDeclarationKind, rightType: Type) {
2465524659
if (kind === AssignmentDeclarationKind.ModuleExports) {
2465624660
for (const prop of getPropertiesOfObjectType(rightType)) {
@@ -24747,18 +24751,23 @@ namespace ts {
2474724751
return false;
2474824752
}
2474924753

24750-
function reportOperatorError(awaitedTypesAreCompatible?: (left: Type, right: Type) => boolean) {
24754+
function reportOperatorError(isRelated?: (left: Type, right: Type) => boolean) {
2475124755
let wouldWorkWithAwait = false;
2475224756
const errNode = errorNode || operatorToken;
24753-
const [leftStr, rightStr] = getTypeNamesForErrorDisplay(leftType, rightType);
24754-
if (awaitedTypesAreCompatible) {
24757+
if (isRelated) {
2475524758
const awaitedLeftType = getAwaitedType(leftType);
2475624759
const awaitedRightType = getAwaitedType(rightType);
2475724760
wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType)
2475824761
&& !!(awaitedLeftType && awaitedRightType)
24759-
&& awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType);
24762+
&& isRelated(awaitedLeftType, awaitedRightType);
2476024763
}
2476124764

24765+
let effectiveLeft = leftType;
24766+
let effectiveRight = rightType;
24767+
if (!wouldWorkWithAwait && isRelated) {
24768+
[effectiveLeft, effectiveRight] = getBaseTypesIfUnrelated(leftType, rightType, isRelated);
24769+
}
24770+
const [leftStr, rightStr] = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight);
2476224771
if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) {
2476324772
errorAndMaybeSuggestAwait(
2476424773
errNode,
@@ -24795,6 +24804,18 @@ namespace ts {
2479524804
}
2479624805
}
2479724806

24807+
function getBaseTypesIfUnrelated(leftType: Type, rightType: Type, isRelated: (left: Type, right: Type) => boolean): [Type, Type] {
24808+
let effectiveLeft = leftType;
24809+
let effectiveRight = rightType;
24810+
const leftBase = getBaseTypeOfLiteralType(leftType);
24811+
const rightBase = getBaseTypeOfLiteralType(rightType);
24812+
if (!isRelated(leftBase, rightBase)) {
24813+
effectiveLeft = leftBase;
24814+
effectiveRight = rightBase;
24815+
}
24816+
return [ effectiveLeft, effectiveRight ];
24817+
}
24818+
2479824819
function isYieldExpressionInClass(node: YieldExpression): boolean {
2479924820
let current: Node = node;
2480024821
let parent = node.parent;

tests/baselines/reference/additionOperatorWithInvalidOperands.errors.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
66
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(25,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'boolean'.
77
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(26,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'number'.
88
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(27,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'Object'.
9-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(30,11): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'true'.
10-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(31,11): error TS2365: Operator '+' cannot be applied to types 'true' and 'false'.
11-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(32,11): error TS2365: Operator '+' cannot be applied to types 'true' and '123'.
9+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(30,11): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'.
10+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(31,11): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'.
11+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(32,11): error TS2365: Operator '+' cannot be applied to types 'boolean' and 'number'.
1212
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(33,11): error TS2365: Operator '+' cannot be applied to types '{}' and '{}'.
1313
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(34,11): error TS2365: Operator '+' cannot be applied to types 'number' and 'Number'.
1414
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(35,11): error TS2365: Operator '+' cannot be applied to types 'number' and '() => void'.
1515
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(36,11): error TS2365: Operator '+' cannot be applied to types 'number' and 'void'.
1616
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(37,11): error TS2365: Operator '+' cannot be applied to types 'number' and 'typeof C'.
17-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(38,11): error TS2365: Operator '+' cannot be applied to types 'E.a' and 'C'.
18-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(39,11): error TS2365: Operator '+' cannot be applied to types 'E.a' and 'void'.
19-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(40,11): error TS2365: Operator '+' cannot be applied to types 'E.a' and 'typeof M'.
17+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(38,11): error TS2365: Operator '+' cannot be applied to types 'E' and 'C'.
18+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(39,11): error TS2365: Operator '+' cannot be applied to types 'E' and 'void'.
19+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts(40,11): error TS2365: Operator '+' cannot be applied to types 'E' and 'typeof M'.
2020

2121

2222
==== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithInvalidOperands.ts (19 errors) ====
@@ -67,13 +67,13 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
6767
// other cases
6868
var r10 = a + true;
6969
~~~~~~~~
70-
!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'true'.
70+
!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'.
7171
var r11 = true + false;
7272
~~~~~~~~~~~~
73-
!!! error TS2365: Operator '+' cannot be applied to types 'true' and 'false'.
73+
!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'boolean'.
7474
var r12 = true + 123;
7575
~~~~~~~~~~
76-
!!! error TS2365: Operator '+' cannot be applied to types 'true' and '123'.
76+
!!! error TS2365: Operator '+' cannot be applied to types 'boolean' and 'number'.
7777
var r13 = {} + {};
7878
~~~~~~~
7979
!!! error TS2365: Operator '+' cannot be applied to types '{}' and '{}'.
@@ -91,10 +91,10 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
9191
!!! error TS2365: Operator '+' cannot be applied to types 'number' and 'typeof C'.
9292
var r18 = E.a + new C();
9393
~~~~~~~~~~~~~
94-
!!! error TS2365: Operator '+' cannot be applied to types 'E.a' and 'C'.
94+
!!! error TS2365: Operator '+' cannot be applied to types 'E' and 'C'.
9595
var r19 = E.a + C.foo();
9696
~~~~~~~~~~~~~
97-
!!! error TS2365: Operator '+' cannot be applied to types 'E.a' and 'void'.
97+
!!! error TS2365: Operator '+' cannot be applied to types 'E' and 'void'.
9898
var r20 = E.a + M;
9999
~~~~~~~
100-
!!! error TS2365: Operator '+' cannot be applied to types 'E.a' and 'typeof M'.
100+
!!! error TS2365: Operator '+' cannot be applied to types 'E' and 'typeof M'.

tests/baselines/reference/additionOperatorWithNullValueAndInvalidOperator.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
55
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(15,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'null'.
66
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(16,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'void'.
77
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(19,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'Number'.
8-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(20,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'true'.
8+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(20,10): error TS2365: Operator '+' cannot be applied to types 'null' and 'boolean'.
99
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(21,10): error TS2365: Operator '+' cannot be applied to types 'null' and '{ a: string; }'.
1010
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(22,11): error TS2365: Operator '+' cannot be applied to types 'null' and 'void'.
1111
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithNullValueAndInvalidOperator.ts(23,11): error TS2365: Operator '+' cannot be applied to types 'null' and '() => void'.
@@ -47,7 +47,7 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
4747
!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'Number'.
4848
var r8 = null + true;
4949
~~~~~~~~~~~
50-
!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'true'.
50+
!!! error TS2365: Operator '+' cannot be applied to types 'null' and 'boolean'.
5151
var r9 = null + { a: '' };
5252
~~~~~~~~~~~~~~~~
5353
!!! error TS2365: Operator '+' cannot be applied to types 'null' and '{ a: string; }'.

tests/baselines/reference/additionOperatorWithUndefinedValueAndInvalidOperands.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
55
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(15,10): error TS2365: Operator '+' cannot be applied to types 'Object' and 'undefined'.
66
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(16,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'void'.
77
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(19,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'Number'.
8-
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(20,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'true'.
8+
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(20,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'boolean'.
99
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(21,10): error TS2365: Operator '+' cannot be applied to types 'undefined' and '{ a: string; }'.
1010
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(22,11): error TS2365: Operator '+' cannot be applied to types 'undefined' and 'void'.
1111
tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithUndefinedValueAndInvalidOperands.ts(23,11): error TS2365: Operator '+' cannot be applied to types 'undefined' and '() => void'.
@@ -47,7 +47,7 @@ tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOpe
4747
!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'Number'.
4848
var r8 = undefined + true;
4949
~~~~~~~~~~~~~~~~
50-
!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'true'.
50+
!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and 'boolean'.
5151
var r9 = undefined + { a: '' };
5252
~~~~~~~~~~~~~~~~~~~~~
5353
!!! error TS2365: Operator '+' cannot be applied to types 'undefined' and '{ a: string; }'.

0 commit comments

Comments
 (0)