Skip to content

Commit 65659d7

Browse files
author
Andy
authored
Don't allow to iterate over 'never' (#22964)
* Don't allow to iterate over 'never' * Include type in error message
1 parent eca3d68 commit 65659d7

24 files changed

+113
-55
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22627,7 +22627,12 @@ namespace ts {
2262722627
* we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
2262822628
* of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
2262922629
*/
22630-
function getIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, allowAsyncIterables: boolean, checkAssignability: boolean): Type {
22630+
function getIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, allowAsyncIterables: boolean, checkAssignability: boolean): Type | undefined {
22631+
if (inputType === neverType) {
22632+
reportTypeNotIterableError(errorNode, inputType, allowAsyncIterables);
22633+
return undefined;
22634+
}
22635+
2263122636
const uplevelIteration = languageVersion >= ScriptTarget.ES2015;
2263222637
const downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
2263322638

@@ -22794,11 +22799,8 @@ namespace ts {
2279422799
const signatures = methodType && getSignaturesOfType(methodType, SignatureKind.Call);
2279522800
if (!some(signatures)) {
2279622801
if (errorNode) {
22797-
error(errorNode,
22798-
allowAsyncIterables
22799-
? Diagnostics.Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
22800-
: Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
2280122802
// only report on the first error
22803+
reportTypeNotIterableError(errorNode, type, allowAsyncIterables);
2280222804
errorNode = undefined;
2280322805
}
2280422806
return undefined;
@@ -22821,6 +22823,12 @@ namespace ts {
2282122823
}
2282222824
}
2282322825

22826+
function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void {
22827+
error(errorNode, allowAsyncIterables
22828+
? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
22829+
: Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, typeToString(type));
22830+
}
22831+
2282422832
/**
2282522833
* This function has very similar logic as getIteratedTypeOfIterable, except that it operates on
2282622834
* Iterators instead of Iterables. Here is the structure:

src/compiler/diagnosticMessages.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,7 @@
16681668
"category": "Error",
16691669
"code": 2487
16701670
},
1671-
"Type must have a '[Symbol.iterator]()' method that returns an iterator.": {
1671+
"Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator.": {
16721672
"category": "Error",
16731673
"code": 2488
16741674
},
@@ -1732,7 +1732,7 @@
17321732
"category": "Error",
17331733
"code": 2503
17341734
},
1735-
"Type must have a '[Symbol.asyncIterator]()' method that returns an async iterator.": {
1735+
"Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.": {
17361736
"category": "Error",
17371737
"code": 2504
17381738
},
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
tests/cases/conformance/es6/yieldExpressions/YieldExpression6_es6.ts(2,9): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/yieldExpressions/YieldExpression6_es6.ts(2,9): error TS2488: Type '() => any' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/yieldExpressions/YieldExpression6_es6.ts (1 errors) ====
55
function* foo() {
66
yield*foo
77
~~~
8-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
8+
!!! error TS2488: Type '() => any' must have a '[Symbol.iterator]()' method that returns an iterator.
99
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
=== tests/cases/conformance/es6/yieldExpressions/YieldExpression6_es6.ts ===
22
function* foo() {
3-
>foo : () => IterableIterator<any>
3+
>foo : () => any
44

55
yield*foo
66
>yield*foo : any
7-
>foo : () => IterableIterator<any>
7+
>foo : () => any
88
}

tests/baselines/reference/for-of14.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/for-ofStatements/for-of14.ts(8,11): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/for-ofStatements/for-of14.ts(8,11): error TS2488: Type 'StringIterator' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/for-ofStatements/for-of14.ts (1 errors) ====
@@ -11,4 +11,4 @@ tests/cases/conformance/es6/for-ofStatements/for-of14.ts(8,11): error TS2488: Ty
1111
var v: string;
1212
for (v of new StringIterator) { } // Should fail because the iterator is not iterable
1313
~~~~~~~~~~~~~~~~~~
14-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
14+
!!! error TS2488: Type 'StringIterator' must have a '[Symbol.iterator]()' method that returns an iterator.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck21.ts(5,13): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck21.ts(5,13): error TS2488: Type 'Bar' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck21.ts (1 errors) ====
@@ -8,5 +8,5 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck21.ts(5,13): erro
88
yield;
99
yield * new Bar;
1010
~~~~~~~
11-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
11+
!!! error TS2488: Type 'Bar' must have a '[Symbol.iterator]()' method that returns an iterator.
1212
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern21.ts(1,5): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/destructuring/iterableArrayPattern21.ts(1,5): error TS2488: Type '{ 0: string; 1: boolean; }' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern21.ts (1 errors) ====
55
var [a, b] = { 0: "", 1: true };
66
~~~~~~
7-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
7+
!!! error TS2488: Type '{ 0: string; 1: boolean; }' must have a '[Symbol.iterator]()' method that returns an iterator.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern22.ts(1,5): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/destructuring/iterableArrayPattern22.ts(1,5): error TS2488: Type '{ 0: string; 1: boolean; }' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern22.ts (1 errors) ====
55
var [...a] = { 0: "", 1: true };
66
~~~~~~
7-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
7+
!!! error TS2488: Type '{ 0: string; 1: boolean; }' must have a '[Symbol.iterator]()' method that returns an iterator.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern23.ts(2,1): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/destructuring/iterableArrayPattern23.ts(2,1): error TS2488: Type '{ 0: string; 1: true; }' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern23.ts (1 errors) ====
55
var a: string, b: boolean;
66
[a, b] = { 0: "", 1: true };
77
~~~~~~
8-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
8+
!!! error TS2488: Type '{ 0: string; 1: true; }' must have a '[Symbol.iterator]()' method that returns an iterator.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tests/cases/conformance/es6/destructuring/iterableArrayPattern24.ts(2,1): error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
1+
tests/cases/conformance/es6/destructuring/iterableArrayPattern24.ts(2,1): error TS2488: Type '{ 0: string; 1: true; }' must have a '[Symbol.iterator]()' method that returns an iterator.
22

33

44
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern24.ts (1 errors) ====
55
var a: string, b: boolean[];
66
[a, ...b] = { 0: "", 1: true };
77
~~~~~~~~~
8-
!!! error TS2488: Type must have a '[Symbol.iterator]()' method that returns an iterator.
8+
!!! error TS2488: Type '{ 0: string; 1: true; }' must have a '[Symbol.iterator]()' method that returns an iterator.

0 commit comments

Comments
 (0)