diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e772c2f0057..4fa3dcf560c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22701,13 +22701,18 @@ namespace ts { // want to say that number is not an array type. But if the input was just // number and string input is allowed, we want to say that number is not an // array type or a string type. + const isIterable = !!getIteratedTypeOfIterable(inputType, /* errorNode */ undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability); const diagnostic = !allowStringInput || hasStringConstituent ? downlevelIteration ? Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator - : Diagnostics.Type_0_is_not_an_array_type + : isIterable + ? Diagnostics.Type_0_is_not_an_array_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators + : Diagnostics.Type_0_is_not_an_array_type : downlevelIteration ? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator - : Diagnostics.Type_0_is_not_an_array_type_or_a_string_type; + : isIterable + ? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators + : Diagnostics.Type_0_is_not_an_array_type_or_a_string_type; error(errorNode, diagnostic, typeToString(arrayType)); } return hasStringConstituent ? stringType : undefined; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2e3377b08eb..bbc00e6fbc6 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1992,6 +1992,14 @@ "category": "Error", "code": 2567 }, + "Type '{0}' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators.": { + "category": "Error", + "code": 2568 + }, + "Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.": { + "category": "Error", + "code": 2569 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", diff --git a/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt b/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt index e608378d7f1..6bb1d505680 100644 --- a/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt +++ b/tests/baselines/reference/ES5For-ofTypeCheck10.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(9,6): error TS2304: Cannot find name 'Symbol'. -tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck10.ts(14,15): error TS2495: Type 'StringIterator' is not an array type or a string type. +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. ==== 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 for (var v of new StringIterator) { } ~~~~~~~~~~~~~~~~~~ -!!! error TS2495: Type 'StringIterator' is not an array type or a string type. \ No newline at end of file +!!! error TS2569: Type 'StringIterator' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators. \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-ofTypeCheck13.errors.txt b/tests/baselines/reference/ES5For-ofTypeCheck13.errors.txt new file mode 100644 index 00000000000..b64781a4873 --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck13.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts(4,19): error TS2569: Type 'Set' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators. + + +==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts (1 errors) ==== + const strSet: Set = new Set() + strSet.add('Hello') + strSet.add('World') + for (const str of strSet) { } + ~~~~~~ +!!! error TS2569: Type 'Set' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators. \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-ofTypeCheck13.js b/tests/baselines/reference/ES5For-ofTypeCheck13.js new file mode 100644 index 00000000000..216aa57f97c --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck13.js @@ -0,0 +1,13 @@ +//// [ES5For-ofTypeCheck13.ts] +const strSet: Set = new Set() +strSet.add('Hello') +strSet.add('World') +for (const str of strSet) { } + +//// [ES5For-ofTypeCheck13.js] +var strSet = new Set(); +strSet.add('Hello'); +strSet.add('World'); +for (var _i = 0, strSet_1 = strSet; _i < strSet_1.length; _i++) { + var str = strSet_1[_i]; +} diff --git a/tests/baselines/reference/ES5For-ofTypeCheck13.symbols b/tests/baselines/reference/ES5For-ofTypeCheck13.symbols new file mode 100644 index 00000000000..14a1fe161a5 --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck13.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts === +const strSet: Set = new Set() +>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 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, --, --)) +>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, --, --)) + +strSet.add('Hello') +>strSet.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) +>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5)) +>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) + +strSet.add('World') +>strSet.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) +>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5)) +>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) + +for (const str of strSet) { } +>str : Symbol(str, Decl(ES5For-ofTypeCheck13.ts, 3, 10)) +>strSet : Symbol(strSet, Decl(ES5For-ofTypeCheck13.ts, 0, 5)) + diff --git a/tests/baselines/reference/ES5For-ofTypeCheck13.types b/tests/baselines/reference/ES5For-ofTypeCheck13.types new file mode 100644 index 00000000000..4812ae8d82c --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck13.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts === +const strSet: Set = new Set() +>strSet : Set +>Set : Set +>new Set() : Set +>Set : SetConstructor + +strSet.add('Hello') +>strSet.add('Hello') : Set +>strSet.add : (value: string) => Set +>strSet : Set +>add : (value: string) => Set +>'Hello' : "Hello" + +strSet.add('World') +>strSet.add('World') : Set +>strSet.add : (value: string) => Set +>strSet : Set +>add : (value: string) => Set +>'World' : "World" + +for (const str of strSet) { } +>str : any +>strSet : Set + diff --git a/tests/baselines/reference/ES5For-ofTypeCheck14.errors.txt b/tests/baselines/reference/ES5For-ofTypeCheck14.errors.txt new file mode 100644 index 00000000000..3a03491f110 --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck14.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts(2,17): error TS2568: Type 'Set' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators. + + +==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts (1 errors) ==== + var union: string | Set + for (const e of union) { } + ~~~~~ +!!! error TS2568: Type 'Set' is not an array type. Use compiler option '--downlevelIteration' to allow iterating of iterators. \ No newline at end of file diff --git a/tests/baselines/reference/ES5For-ofTypeCheck14.js b/tests/baselines/reference/ES5For-ofTypeCheck14.js new file mode 100644 index 00000000000..87e55c41a0e --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck14.js @@ -0,0 +1,9 @@ +//// [ES5For-ofTypeCheck14.ts] +var union: string | Set +for (const e of union) { } + +//// [ES5For-ofTypeCheck14.js] +var union; +for (var _i = 0, union_1 = union; _i < union_1.length; _i++) { + var e = union_1[_i]; +} diff --git a/tests/baselines/reference/ES5For-ofTypeCheck14.symbols b/tests/baselines/reference/ES5For-ofTypeCheck14.symbols new file mode 100644 index 00000000000..efa7d296d9d --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck14.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts === +var union: string | Set +>union : Symbol(union, Decl(ES5For-ofTypeCheck14.ts, 0, 3)) +>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, --, --)) + +for (const e of union) { } +>e : Symbol(e, Decl(ES5For-ofTypeCheck14.ts, 1, 10)) +>union : Symbol(union, Decl(ES5For-ofTypeCheck14.ts, 0, 3)) + diff --git a/tests/baselines/reference/ES5For-ofTypeCheck14.types b/tests/baselines/reference/ES5For-ofTypeCheck14.types new file mode 100644 index 00000000000..03a822316ac --- /dev/null +++ b/tests/baselines/reference/ES5For-ofTypeCheck14.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts === +var union: string | Set +>union : string | Set +>Set : Set + +for (const e of union) { } +>e : string +>union : string | Set + diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts new file mode 100644 index 00000000000..e6748b9373b --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts @@ -0,0 +1,6 @@ +//@target: ES5 +//@lib: ES6 +const strSet: Set = new Set() +strSet.add('Hello') +strSet.add('World') +for (const str of strSet) { } \ No newline at end of file diff --git a/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts b/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts new file mode 100644 index 00000000000..9474fcec5d9 --- /dev/null +++ b/tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts @@ -0,0 +1,4 @@ +//@target: ES5 +//@lib: ES6 +var union: string | Set +for (const e of union) { } \ No newline at end of file