Skip to content

Commit e3f02b5

Browse files
authored
Merge pull request #22275 from delftswa2018/21617-detailed-error-forof-iterators
Fix #21617: Give detailed message on `for-of` of iterators without downlevelIteration
2 parents 24dbc9e + d716e21 commit e3f02b5

13 files changed

+130
-4
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22701,13 +22701,18 @@ namespace ts {
2270122701
// want to say that number is not an array type. But if the input was just
2270222702
// number and string input is allowed, we want to say that number is not an
2270322703
// array type or a string type.
22704+
const isIterable = !!getIteratedTypeOfIterable(inputType, /* errorNode */ undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability);
2270422705
const diagnostic = !allowStringInput || hasStringConstituent
2270522706
? downlevelIteration
2270622707
? Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
22707-
: Diagnostics.Type_0_is_not_an_array_type
22708+
: isIterable
22709+
? Diagnostics.Type_0_is_not_an_array_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators
22710+
: Diagnostics.Type_0_is_not_an_array_type
2270822711
: downlevelIteration
2270922712
? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
22710-
: Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
22713+
: isIterable
22714+
? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators
22715+
: Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
2271122716
error(errorNode, diagnostic, typeToString(arrayType));
2271222717
}
2271322718
return hasStringConstituent ? stringType : undefined;

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,14 @@
19921992
"category": "Error",
19931993
"code": 2567
19941994
},
1995+
"Type '{0}' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators.": {
1996+
"category": "Error",
1997+
"code": 2568
1998+
},
1999+
"Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.": {
2000+
"category": "Error",
2001+
"code": 2569
2002+
},
19952003

19962004
"JSX element attributes type '{0}' may not be a union type.": {
19972005
"category": "Error",

tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(9,6): error TS2304: Cannot find name 'Symbol'.
2-
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(14,15): error TS2495: Type 'StringIterator' is not an array type or a string type.
2+
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(14,15): error TS2569: Type 'StringIterator' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
33

44

55
==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts (2 errors) ====
@@ -20,4 +20,4 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(14,1
2020

2121
for (var v of new StringIterator) { }
2222
~~~~~~~~~~~~~~~~~~
23-
!!! error TS2495: Type 'StringIterator' is not an array type or a string type.
23+
!!! error TS2569: Type 'StringIterator' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts(4,19): error TS2569: Type 'Set<string>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
2+
3+
4+
==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts (1 errors) ====
5+
const strSet: Set<string> = new Set()
6+
strSet.add('Hello')
7+
strSet.add('World')
8+
for (const str of strSet) { }
9+
~~~~~~
10+
!!! error TS2569: Type 'Set<string>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [ES5For-ofTypeCheck13.ts]
2+
const strSet: Set<string> = new Set()
3+
strSet.add('Hello')
4+
strSet.add('World')
5+
for (const str of strSet) { }
6+
7+
//// [ES5For-ofTypeCheck13.js]
8+
var strSet = new Set();
9+
strSet.add('Hello');
10+
strSet.add('World');
11+
for (var _i = 0, strSet_1 = strSet; _i < strSet_1.length; _i++) {
12+
var str = strSet_1[_i];
13+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts ===
2+
const strSet: Set<string> = new Set()
3+
>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5))
4+
>Set : Symbol(Set, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --))
5+
>Set : Symbol(Set, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --))
6+
7+
strSet.add('Hello')
8+
>strSet.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --))
9+
>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5))
10+
>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --))
11+
12+
strSet.add('World')
13+
>strSet.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --))
14+
>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5))
15+
>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --))
16+
17+
for (const str of strSet) { }
18+
>str : Symbol(str, Decl(ES5For-ofTypeCheck13.ts, 3, 10))
19+
>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5))
20+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts ===
2+
const strSet: Set<string> = new Set()
3+
>strSet : Set<string>
4+
>Set : Set<T>
5+
>new Set() : Set<any>
6+
>Set : SetConstructor
7+
8+
strSet.add('Hello')
9+
>strSet.add('Hello') : Set<string>
10+
>strSet.add : (value: string) => Set<string>
11+
>strSet : Set<string>
12+
>add : (value: string) => Set<string>
13+
>'Hello' : "Hello"
14+
15+
strSet.add('World')
16+
>strSet.add('World') : Set<string>
17+
>strSet.add : (value: string) => Set<string>
18+
>strSet : Set<string>
19+
>add : (value: string) => Set<string>
20+
>'World' : "World"
21+
22+
for (const str of strSet) { }
23+
>str : any
24+
>strSet : Set<string>
25+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts(2,17): error TS2568: Type 'Set<number>' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
2+
3+
4+
==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts (1 errors) ====
5+
var union: string | Set<number>
6+
for (const e of union) { }
7+
~~~~~
8+
!!! error TS2568: Type 'Set<number>' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//// [ES5For-ofTypeCheck14.ts]
2+
var union: string | Set<number>
3+
for (const e of union) { }
4+
5+
//// [ES5For-ofTypeCheck14.js]
6+
var union;
7+
for (var _i = 0, union_1 = union; _i < union_1.length; _i++) {
8+
var e = union_1[_i];
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts ===
2+
var union: string | Set<number>
3+
>union : Symbol(union, Decl(ES5For-ofTypeCheck14.ts, 0, 3))
4+
>Set : Symbol(Set, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --))
5+
6+
for (const e of union) { }
7+
>e : Symbol(e, Decl(ES5For-ofTypeCheck14.ts, 1, 10))
8+
>union : Symbol(union, Decl(ES5For-ofTypeCheck14.ts, 0, 3))
9+

0 commit comments

Comments
 (0)