Skip to content

Commit ec93a7c

Browse files
authored
fix(36055): forbid union type with invalid types in the 'in' operator (#37786)
1 parent 8746d17 commit ec93a7c

10 files changed

+251
-137
lines changed

src/compiler/checker.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -28034,7 +28034,8 @@ namespace ts {
2803428034
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
2803528035
// and the right operand to be of type Any, an object type, or a type parameter type.
2803628036
// The result is always of the Boolean primitive type.
28037-
if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbolLike))) {
28037+
if (!(allTypesAssignableToKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) ||
28038+
isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TypeParameter))) {
2803828039
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
2803928040
}
2804028041
if (!allTypesAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) {

tests/baselines/reference/inOperatorWithInvalidOperands.errors.txt

+29-19
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
1-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(12,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
2-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(13,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
3-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(14,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
4-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2531: Object is possibly 'null'.
5-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2532: Object is possibly 'undefined'.
6-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
7-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
8-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(30,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
9-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(31,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
10-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(32,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
11-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(33,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
12-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(34,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
1+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(15,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
2+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(16,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
3+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(17,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
4+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(19,11): error TS2531: Object is possibly 'null'.
5+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(20,11): error TS2532: Object is possibly 'undefined'.
6+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(22,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
7+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(23,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
8+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(24,12): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
9+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(25,12): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
1310
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(35,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
1411
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(36,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
1512
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(37,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
16-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(38,16): error TS2531: Object is possibly 'null'.
17-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(39,17): error TS2532: Object is possibly 'undefined'.
18-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
19-
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
13+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(38,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
14+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(39,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
15+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(40,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
16+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(41,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
17+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(42,16): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
18+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(43,16): error TS2531: Object is possibly 'null'.
19+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(44,17): error TS2532: Object is possibly 'undefined'.
20+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(47,11): error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
21+
tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts(47,17): error TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
2022

2123

22-
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (19 errors) ====
24+
==== tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInvalidOperands.ts (21 errors) ====
25+
class Foo {}
2326
enum E { a }
2427

2528
var x: any;
@@ -29,7 +32,9 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
2932
var a1: boolean;
3033
var a2: void;
3134
var a3: {};
32-
var a4: E
35+
var a4: E;
36+
var a5: Foo | string;
37+
var a6: Foo;
3338

3439
var ra1 = a1 in x;
3540
~~
@@ -54,6 +59,12 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
5459
var ra9 = {} in x;
5560
~~
5661
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
62+
var ra10 = a5 in x;
63+
~~
64+
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
65+
var ra11 = a6 in x;
66+
~~
67+
!!! error TS2360: The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'.
5768

5869
// invalid right operands
5970
// the right operand is required to be of type Any, an object type, or a type parameter type
@@ -94,7 +105,6 @@ tests/cases/conformance/expressions/binaryOperators/inOperator/inOperatorWithInv
94105
~~~~~~~~~
95106
!!! error TS2532: Object is possibly 'undefined'.
96107

97-
98108
// both operands are invalid
99109
var rc1 = {} in '';
100110
~~

tests/baselines/reference/inOperatorWithInvalidOperands.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//// [inOperatorWithInvalidOperands.ts]
2+
class Foo {}
23
enum E { a }
34

45
var x: any;
@@ -8,7 +9,9 @@ var x: any;
89
var a1: boolean;
910
var a2: void;
1011
var a3: {};
11-
var a4: E
12+
var a4: E;
13+
var a5: Foo | string;
14+
var a6: Foo;
1215

1316
var ra1 = a1 in x;
1417
var ra2 = a2 in x;
@@ -19,6 +22,8 @@ var ra6 = undefined in x;
1922
var ra7 = E.a in x;
2023
var ra8 = false in x;
2124
var ra9 = {} in x;
25+
var ra10 = a5 in x;
26+
var ra11 = a6 in x;
2227

2328
// invalid right operands
2429
// the right operand is required to be of type Any, an object type, or a type parameter type
@@ -39,11 +44,15 @@ var rb8 = x in '';
3944
var rb9 = x in null;
4045
var rb10 = x in undefined;
4146

42-
4347
// both operands are invalid
4448
var rc1 = {} in '';
4549

4650
//// [inOperatorWithInvalidOperands.js]
51+
var Foo = /** @class */ (function () {
52+
function Foo() {
53+
}
54+
return Foo;
55+
}());
4756
var E;
4857
(function (E) {
4958
E[E["a"] = 0] = "a";
@@ -55,6 +64,8 @@ var a1;
5564
var a2;
5665
var a3;
5766
var a4;
67+
var a5;
68+
var a6;
5869
var ra1 = a1 in x;
5970
var ra2 = a2 in x;
6071
var ra3 = a3 in x;
@@ -64,6 +75,8 @@ var ra6 = undefined in x;
6475
var ra7 = E.a in x;
6576
var ra8 = false in x;
6677
var ra9 = {} in x;
78+
var ra10 = a5 in x;
79+
var ra11 = a6 in x;
6780
// invalid right operands
6881
// the right operand is required to be of type Any, an object type, or a type parameter type
6982
var b1;

0 commit comments

Comments
 (0)