Skip to content

Commit 87c291e

Browse files
authored
Merge pull request #14195 from HerringtonDarkholme/object-iteration
fix #14187, forIn should allow non primitive object as right hand side
2 parents 868802b + 5196607 commit 87c291e

12 files changed

+128
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18788,7 +18788,7 @@ namespace ts {
1878818788

1878918789
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
1879018790
// in this case error about missing name is already reported - do not report extra one
18791-
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable)) {
18791+
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.NonPrimitive)) {
1879218792
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
1879318793
}
1879418794

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [nonPrimitiveIndexingWithForIn.ts]
2+
var a: object;
3+
4+
for (var key in a) {
5+
var value = a[key];
6+
}
7+
8+
9+
//// [nonPrimitiveIndexingWithForIn.js]
10+
var a;
11+
for (var key in a) {
12+
var value = a[key];
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts ===
2+
var a: object;
3+
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3))
4+
5+
for (var key in a) {
6+
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForIn.ts, 2, 8))
7+
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3))
8+
9+
var value = a[key];
10+
>value : Symbol(value, Decl(nonPrimitiveIndexingWithForIn.ts, 3, 7))
11+
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForIn.ts, 0, 3))
12+
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForIn.ts, 2, 8))
13+
}
14+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForIn.ts ===
2+
var a: object;
3+
>a : object
4+
5+
for (var key in a) {
6+
>key : string
7+
>a : object
8+
9+
var value = a[key];
10+
>value : any
11+
>a[key] : any
12+
>a : object
13+
>key : string
14+
}
15+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts(4,17): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
2+
3+
4+
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts (1 errors) ====
5+
var a: object;
6+
7+
for (var key in a) {
8+
var value = a[key]; // error
9+
~~~~~~
10+
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
11+
}
12+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [nonPrimitiveIndexingWithForInNoImplicitAny.ts]
2+
var a: object;
3+
4+
for (var key in a) {
5+
var value = a[key]; // error
6+
}
7+
8+
9+
//// [nonPrimitiveIndexingWithForInNoImplicitAny.js]
10+
var a;
11+
for (var key in a) {
12+
var value = a[key]; // error
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [nonPrimitiveIndexingWithForInSupressError.ts]
2+
var a: object;
3+
4+
for (var key in a) {
5+
var value = a[key];
6+
}
7+
8+
9+
//// [nonPrimitiveIndexingWithForInSupressError.js]
10+
var a;
11+
for (var key in a) {
12+
var value = a[key];
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts ===
2+
var a: object;
3+
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3))
4+
5+
for (var key in a) {
6+
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 2, 8))
7+
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3))
8+
9+
var value = a[key];
10+
>value : Symbol(value, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 3, 7))
11+
>a : Symbol(a, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 0, 3))
12+
>key : Symbol(key, Decl(nonPrimitiveIndexingWithForInSupressError.ts, 2, 8))
13+
}
14+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInSupressError.ts ===
2+
var a: object;
3+
>a : object
4+
5+
for (var key in a) {
6+
>key : string
7+
>a : object
8+
9+
var value = a[key];
10+
>value : any
11+
>a[key] : any
12+
>a : object
13+
>key : string
14+
}
15+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var a: object;
2+
3+
for (var key in a) {
4+
var value = a[key];
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @noImplicitAny: true
2+
var a: object;
3+
4+
for (var key in a) {
5+
var value = a[key]; // error
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @noImplicitAny: true
2+
// @suppressImplicitAnyIndexErrors: true
3+
var a: object;
4+
5+
for (var key in a) {
6+
var value = a[key];
7+
}

0 commit comments

Comments
 (0)