From 39d1c8b84490eb1da66ef15396188430635723c6 Mon Sep 17 00:00:00 2001 From: kpreisser Date: Sun, 5 Mar 2017 14:25:59 +0100 Subject: [PATCH 1/2] Allow the right-hand side of an 'in' expression to be of non-primitive object type. Fixes #14269 --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a4c0acc405d5e..300fc2e8beffa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15546,7 +15546,7 @@ namespace ts { if (!(isTypeComparableTo(leftType, stringType) || isTypeOfKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbol))) { error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive)) { error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; From 6d02d1fde8ef223b9ac828603112953e8f697df1 Mon Sep 17 00:00:00 2001 From: kpreisser Date: Sun, 5 Mar 2017 14:38:16 +0100 Subject: [PATCH 2/2] Add tests. --- .../nonPrimitiveRhsSideOfInExpression.js | 17 +++++++++++++ .../nonPrimitiveRhsSideOfInExpression.symbols | 18 +++++++++++++ .../nonPrimitiveRhsSideOfInExpression.types | 25 +++++++++++++++++++ .../nonPrimitiveRhsSideOfInExpression.ts | 8 ++++++ 4 files changed, 68 insertions(+) create mode 100644 tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.js create mode 100644 tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.symbols create mode 100644 tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.types create mode 100644 tests/cases/conformance/types/nonPrimitive/nonPrimitiveRhsSideOfInExpression.ts diff --git a/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.js b/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.js new file mode 100644 index 0000000000000..4b08610199be9 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.js @@ -0,0 +1,17 @@ +//// [nonPrimitiveRhsSideOfInExpression.ts] +let o: object = {}; + +function f(): object { + return {}; +} + +const b1 = "foo" in o; +const b2 = "bar" in f(); + +//// [nonPrimitiveRhsSideOfInExpression.js] +var o = {}; +function f() { + return {}; +} +var b1 = "foo" in o; +var b2 = "bar" in f(); diff --git a/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.symbols b/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.symbols new file mode 100644 index 0000000000000..914f77322a53f --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveRhsSideOfInExpression.ts === +let o: object = {}; +>o : Symbol(o, Decl(nonPrimitiveRhsSideOfInExpression.ts, 0, 3)) + +function f(): object { +>f : Symbol(f, Decl(nonPrimitiveRhsSideOfInExpression.ts, 0, 19)) + + return {}; +} + +const b1 = "foo" in o; +>b1 : Symbol(b1, Decl(nonPrimitiveRhsSideOfInExpression.ts, 6, 5)) +>o : Symbol(o, Decl(nonPrimitiveRhsSideOfInExpression.ts, 0, 3)) + +const b2 = "bar" in f(); +>b2 : Symbol(b2, Decl(nonPrimitiveRhsSideOfInExpression.ts, 7, 5)) +>f : Symbol(f, Decl(nonPrimitiveRhsSideOfInExpression.ts, 0, 19)) + diff --git a/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.types b/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.types new file mode 100644 index 0000000000000..45c8864e43e4c --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveRhsSideOfInExpression.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveRhsSideOfInExpression.ts === +let o: object = {}; +>o : object +>{} : {} + +function f(): object { +>f : () => object + + return {}; +>{} : {} +} + +const b1 = "foo" in o; +>b1 : boolean +>"foo" in o : boolean +>"foo" : "foo" +>o : object + +const b2 = "bar" in f(); +>b2 : boolean +>"bar" in f() : boolean +>"bar" : "bar" +>f() : object +>f : () => object + diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveRhsSideOfInExpression.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveRhsSideOfInExpression.ts new file mode 100644 index 0000000000000..f2a02c7a59afb --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveRhsSideOfInExpression.ts @@ -0,0 +1,8 @@ +let o: object = {}; + +function f(): object { + return {}; +} + +const b1 = "foo" in o; +const b2 = "bar" in f(); \ No newline at end of file