Skip to content

Commit efbe03a

Browse files
authored
check base constraint when checking operand of plus (microsoft#49918)
1 parent aa2b235 commit efbe03a

File tree

6 files changed

+69
-5
lines changed

6 files changed

+69
-5
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33439,7 +33439,7 @@ namespace ts {
3343933439
error(node.operand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(node.operator));
3344033440
}
3344133441
if (node.operator === SyntaxKind.PlusToken) {
33442-
if (maybeTypeOfKind(operandType, TypeFlags.BigIntLike)) {
33442+
if (maybeTypeOfKindConsideringBaseConstraint(operandType, TypeFlags.BigIntLike)) {
3344333443
error(node.operand, Diagnostics.Operator_0_cannot_be_applied_to_type_1, tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType)));
3344433444
}
3344533445
return numberType;

tests/baselines/reference/numberVsBigIntOperations.errors.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ tests/cases/compiler/numberVsBigIntOperations.ts(61,1): error TS2365: Operator '
6262
tests/cases/compiler/numberVsBigIntOperations.ts(70,2): error TS2736: Operator '+' cannot be applied to type 'number | bigint'.
6363
tests/cases/compiler/numberVsBigIntOperations.ts(86,7): error TS1155: 'const' declarations must be initialized.
6464
tests/cases/compiler/numberVsBigIntOperations.ts(93,7): error TS1155: 'const' declarations must be initialized.
65+
tests/cases/compiler/numberVsBigIntOperations.ts(98,6): error TS2736: Operator '+' cannot be applied to type 'S'.
66+
tests/cases/compiler/numberVsBigIntOperations.ts(99,5): error TS2365: Operator '+' cannot be applied to types 'number' and 'S'.
6567

6668

67-
==== tests/cases/compiler/numberVsBigIntOperations.ts (64 errors) ====
69+
==== tests/cases/compiler/numberVsBigIntOperations.ts (66 errors) ====
6870
// Cannot mix bigints and numbers
6971
let bigInt = 1n, num = 2;
7072
bigInt = 1n; bigInt = 2; num = 1n; num = 2;
@@ -286,4 +288,15 @@ tests/cases/compiler/numberVsBigIntOperations.ts(93,7): error TS1155: 'const' de
286288
const bigZeroOrOne: 0n | 1;
287289
~~~~~~~~~~~~
288290
!!! error TS1155: 'const' declarations must be initialized.
289-
if (bigZeroOrOne) isOne(bigZeroOrOne);
291+
if (bigZeroOrOne) isOne(bigZeroOrOne);
292+
293+
type NumberOrBigint = number | bigint;
294+
function getKey<S extends NumberOrBigint>(key: S) {
295+
+key; // should error
296+
~~~
297+
!!! error TS2736: Operator '+' cannot be applied to type 'S'.
298+
0 + key; // should error
299+
~~~~~~~
300+
!!! error TS2365: Operator '+' cannot be applied to types 'number' and 'S'.
301+
}
302+

tests/baselines/reference/numberVsBigIntOperations.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,14 @@ else isNumber(zeroOrBigOne);
9292
const isOne = (x: 1 | 1n) => x;
9393
if (zeroOrBigOne) isOne(zeroOrBigOne);
9494
const bigZeroOrOne: 0n | 1;
95-
if (bigZeroOrOne) isOne(bigZeroOrOne);
95+
if (bigZeroOrOne) isOne(bigZeroOrOne);
96+
97+
type NumberOrBigint = number | bigint;
98+
function getKey<S extends NumberOrBigint>(key: S) {
99+
+key; // should error
100+
0 + key; // should error
101+
}
102+
96103

97104
//// [numberVsBigIntOperations.js]
98105
// Cannot mix bigints and numbers
@@ -272,3 +279,7 @@ if (zeroOrBigOne)
272279
const bigZeroOrOne;
273280
if (bigZeroOrOne)
274281
isOne(bigZeroOrOne);
282+
function getKey(key) {
283+
+key; // should error
284+
0 + key; // should error
285+
}

tests/baselines/reference/numberVsBigIntOperations.symbols

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,3 +348,20 @@ if (bigZeroOrOne) isOne(bigZeroOrOne);
348348
>isOne : Symbol(isOne, Decl(numberVsBigIntOperations.ts, 90, 5))
349349
>bigZeroOrOne : Symbol(bigZeroOrOne, Decl(numberVsBigIntOperations.ts, 92, 5))
350350

351+
type NumberOrBigint = number | bigint;
352+
>NumberOrBigint : Symbol(NumberOrBigint, Decl(numberVsBigIntOperations.ts, 93, 38))
353+
354+
function getKey<S extends NumberOrBigint>(key: S) {
355+
>getKey : Symbol(getKey, Decl(numberVsBigIntOperations.ts, 95, 38))
356+
>S : Symbol(S, Decl(numberVsBigIntOperations.ts, 96, 16))
357+
>NumberOrBigint : Symbol(NumberOrBigint, Decl(numberVsBigIntOperations.ts, 93, 38))
358+
>key : Symbol(key, Decl(numberVsBigIntOperations.ts, 96, 42))
359+
>S : Symbol(S, Decl(numberVsBigIntOperations.ts, 96, 16))
360+
361+
+key; // should error
362+
>key : Symbol(key, Decl(numberVsBigIntOperations.ts, 96, 42))
363+
364+
0 + key; // should error
365+
>key : Symbol(key, Decl(numberVsBigIntOperations.ts, 96, 42))
366+
}
367+

tests/baselines/reference/numberVsBigIntOperations.types

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,3 +727,20 @@ if (bigZeroOrOne) isOne(bigZeroOrOne);
727727
>isOne : (x: 1n | 1) => 1n | 1
728728
>bigZeroOrOne : 1
729729

730+
type NumberOrBigint = number | bigint;
731+
>NumberOrBigint : number | bigint
732+
733+
function getKey<S extends NumberOrBigint>(key: S) {
734+
>getKey : <S extends NumberOrBigint>(key: S) => void
735+
>key : S
736+
737+
+key; // should error
738+
>+key : number
739+
>key : S
740+
741+
0 + key; // should error
742+
>0 + key : any
743+
>0 : 0
744+
>key : S
745+
}
746+

tests/cases/compiler/numberVsBigIntOperations.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,10 @@ else isNumber(zeroOrBigOne);
9393
const isOne = (x: 1 | 1n) => x;
9494
if (zeroOrBigOne) isOne(zeroOrBigOne);
9595
const bigZeroOrOne: 0n | 1;
96-
if (bigZeroOrOne) isOne(bigZeroOrOne);
96+
if (bigZeroOrOne) isOne(bigZeroOrOne);
97+
98+
type NumberOrBigint = number | bigint;
99+
function getKey<S extends NumberOrBigint>(key: S) {
100+
+key; // should error
101+
0 + key; // should error
102+
}

0 commit comments

Comments
 (0)