@@ -4117,7 +4117,7 @@ namespace ts {
4117
4117
// This elementType will be used if the specific property corresponding to this index is not
4118
4118
// present (aka the tuple element property). This call also checks that the parentType is in
4119
4119
// fact an iterable or array (depending on target language).
4120
- const elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false, /*allowAsyncIterable */ false);
4120
+ const elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false, /*allowAsyncIterables */ false);
4121
4121
if (declaration.dotDotDotToken) {
4122
4122
// Rest element has an array type with the same element type as the parent type
4123
4123
type = createArrayType(elementType);
@@ -10888,12 +10888,12 @@ namespace ts {
10888
10888
10889
10889
function getTypeOfDestructuredArrayElement(type: Type, index: number) {
10890
10890
return isTupleLikeType(type) && getTypeOfPropertyOfType(type, "" + index) ||
10891
- checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterable */ false) ||
10891
+ checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables */ false) ||
10892
10892
unknownType;
10893
10893
}
10894
10894
10895
10895
function getTypeOfDestructuredSpreadExpression(type: Type) {
10896
- return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterable */ false) || unknownType);
10896
+ return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables */ false) || unknownType);
10897
10897
}
10898
10898
10899
10899
function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type {
@@ -12867,7 +12867,7 @@ namespace ts {
12867
12867
const index = indexOf(arrayLiteral.elements, node);
12868
12868
return getTypeOfPropertyOfContextualType(type, "" + index)
12869
12869
|| getIndexTypeOfContextualType(type, IndexKind.Number)
12870
- || getIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterable */ false, /*checkAssignability*/ false);
12870
+ || getIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables */ false, /*checkAssignability*/ false);
12871
12871
}
12872
12872
return undefined;
12873
12873
}
@@ -13105,7 +13105,7 @@ namespace ts {
13105
13105
}
13106
13106
13107
13107
const arrayOrIterableType = checkExpression(node.expression, checkMode);
13108
- return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterable */ false);
13108
+ return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterables */ false);
13109
13109
}
13110
13110
13111
13111
function hasDefaultValue(node: BindingElement | Expression): boolean {
@@ -13134,7 +13134,7 @@ namespace ts {
13134
13134
// if there is no index type / iterated type.
13135
13135
const restArrayType = checkExpression((<SpreadElement>e).expression, checkMode);
13136
13136
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
13137
- getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterable */ false, /*checkAssignability*/ false);
13137
+ getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables */ false, /*checkAssignability*/ false);
13138
13138
if (restElementType) {
13139
13139
elementTypes.push(restElementType);
13140
13140
}
@@ -16987,7 +16987,7 @@ namespace ts {
16987
16987
// This elementType will be used if the specific property corresponding to this index is not
16988
16988
// present (aka the tuple element property). This call also checks that the parentType is in
16989
16989
// fact an iterable or array (depending on target language).
16990
- const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterable */ false) || unknownType;
16990
+ const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables */ false) || unknownType;
16991
16991
const elements = node.elements;
16992
16992
for (let i = 0; i < elements.length; i++) {
16993
16993
checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
@@ -20131,29 +20131,29 @@ namespace ts {
20131
20131
return checkIteratedTypeOrElementType(expressionType, rhsExpression, /*allowStringInput*/ true, awaitModifier !== undefined);
20132
20132
}
20133
20133
20134
- function checkIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, allowAsyncIterable : boolean): Type {
20134
+ function checkIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, allowAsyncIterables : boolean): Type {
20135
20135
if (isTypeAny(inputType)) {
20136
20136
return inputType;
20137
20137
}
20138
20138
20139
- return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterable , /*checkAssignability*/ true) || anyType;
20139
+ return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables , /*checkAssignability*/ true) || anyType;
20140
20140
}
20141
20141
20142
20142
/**
20143
20143
* When consuming an iterable type in a for..of, spread, or iterator destructuring assignment
20144
20144
* we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
20145
20145
* of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
20146
20146
*/
20147
- function getIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, allowAsyncIterable : boolean, checkAssignability: boolean): Type {
20147
+ function getIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean, allowAsyncIterables : boolean, checkAssignability: boolean): Type {
20148
20148
const uplevelIteration = languageVersion >= ScriptTarget.ES2015;
20149
20149
const downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
20150
20150
20151
20151
// Get the iterated type of an `Iterable<T>` or `IterableIterator<T>` only in ES2015
20152
20152
// or higher, when inside of an async generator or for-await-if, or when
20153
20153
// downlevelIteration is requested.
20154
- if (uplevelIteration || downlevelIteration || allowAsyncIterable ) {
20154
+ if (uplevelIteration || downlevelIteration || allowAsyncIterables ) {
20155
20155
// We only report errors for an invalid iterable type in ES2015 or higher.
20156
- const iteratedType = getIteratedTypeOfIterable(inputType, uplevelIteration ? errorNode : undefined, allowAsyncIterable, allowAsyncIterable , checkAssignability);
20156
+ const iteratedType = getIteratedTypeOfIterable(inputType, uplevelIteration ? errorNode : undefined, allowAsyncIterables, /*allowSyncIterables*/ true , checkAssignability);
20157
20157
if (iteratedType || uplevelIteration) {
20158
20158
return iteratedType;
20159
20159
}
@@ -20267,79 +20267,75 @@ namespace ts {
20267
20267
* For a **for-await-of** statement or a `yield*` in an async generator we will look for
20268
20268
* the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
20269
20269
*/
20270
- function getIteratedTypeOfIterable(type: Type, errorNode: Node | undefined, isAsyncIterable : boolean, allowNonAsyncIterables : boolean, checkAssignability: boolean): Type | undefined {
20270
+ function getIteratedTypeOfIterable(type: Type, errorNode: Node | undefined, allowAsyncIterables : boolean, allowSyncIterables : boolean, checkAssignability: boolean): Type | undefined {
20271
20271
if (isTypeAny(type)) {
20272
20272
return undefined;
20273
20273
}
20274
20274
20275
- const typeAsIterable = <IterableOrIteratorType>type;
20276
- if (isAsyncIterable ? typeAsIterable.iteratedTypeOfAsyncIterable : typeAsIterable.iteratedTypeOfIterable) {
20277
- return isAsyncIterable ? typeAsIterable.iteratedTypeOfAsyncIterable : typeAsIterable.iteratedTypeOfIterable;
20278
- }
20275
+ return mapType(type, getIteratedType);
20276
+
20277
+ function getIteratedType(type: Type) {
20278
+ const typeAsIterable = <IterableOrIteratorType>type;
20279
+ if (allowAsyncIterables) {
20280
+ if (typeAsIterable.iteratedTypeOfAsyncIterable) {
20281
+ return typeAsIterable.iteratedTypeOfAsyncIterable;
20282
+ }
20279
20283
20280
- if (isAsyncIterable) {
20281
- // As an optimization, if the type is an instantiation of the global `AsyncIterable <T>`
20282
- // or the global `AsyncIterableIterator<T>` then just grab its type argument.
20283
- if ( isReferenceToType(type, getGlobalAsyncIterableType (/*reportErrors*/ false)) ||
20284
- isReferenceToType(type, getGlobalAsyncIterableIteratorType(/*reportErrors*/ false))) {
20285
- return typeAsIterable.iteratedTypeOfAsyncIterable = (<GenericType>type).typeArguments[0];
20284
+ // As an optimization, if the type is an instantiation of the global `AsyncIterable<T>`
20285
+ // or the global `AsyncIterableIterator <T>` then just grab its type argument.
20286
+ if (isReferenceToType(type, getGlobalAsyncIterableType(/*reportErrors*/ false)) ||
20287
+ isReferenceToType(type, getGlobalAsyncIterableIteratorType (/*reportErrors*/ false))) {
20288
+ return typeAsIterable.iteratedTypeOfAsyncIterable = (<GenericType>type).typeArguments[0];
20289
+ }
20286
20290
}
20287
- }
20288
20291
20289
- if (!isAsyncIterable || allowNonAsyncIterables) {
20290
- // As an optimization, if the type is an instantiation of the global `Iterable<T>` or
20291
- // `IterableIterator<T>` then just grab its type argument.
20292
- if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) ||
20293
- isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) {
20294
- return isAsyncIterable
20295
- ? typeAsIterable.iteratedTypeOfAsyncIterable = (<GenericType>type).typeArguments[0]
20296
- : typeAsIterable.iteratedTypeOfIterable = (<GenericType>type).typeArguments[0];
20292
+ if (allowSyncIterables) {
20293
+ if (typeAsIterable.iteratedTypeOfIterable) {
20294
+ return typeAsIterable.iteratedTypeOfIterable;
20295
+ }
20296
+
20297
+ // As an optimization, if the type is an instantiation of the global `Iterable<T>` or
20298
+ // `IterableIterator<T>` then just grab its type argument.
20299
+ if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) ||
20300
+ isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) {
20301
+ return typeAsIterable.iteratedTypeOfIterable = (<GenericType>type).typeArguments[0];
20302
+ }
20297
20303
}
20298
- }
20299
20304
20300
- let iteratorMethodSignatures: Signature[];
20301
- let isNonAsyncIterable = false;
20302
- if (isAsyncIterable) {
20303
- const iteratorMethod = getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("asyncIterator"));
20304
- if (isTypeAny(iteratorMethod)) {
20305
+ const asyncMethodType = allowAsyncIterables && getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("asyncIterator"));
20306
+ const methodType = asyncMethodType || (allowSyncIterables && getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("iterator")));
20307
+ if (isTypeAny(methodType)) {
20305
20308
return undefined;
20306
20309
}
20307
- iteratorMethodSignatures = iteratorMethod && getSignaturesOfType(iteratorMethod, SignatureKind.Call);
20308
- }
20309
20310
20310
- if (!isAsyncIterable || (allowNonAsyncIterables && !some(iteratorMethodSignatures))) {
20311
- const iteratorMethod = getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("iterator"));
20312
- if (isTypeAny(iteratorMethod)) {
20311
+ const signatures = methodType && getSignaturesOfType(methodType, SignatureKind.Call);
20312
+ if (!some(signatures)) {
20313
+ if (errorNode) {
20314
+ error(errorNode,
20315
+ allowAsyncIterables
20316
+ ? Diagnostics.Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
20317
+ : Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
20318
+ // only report on the first error
20319
+ errorNode = undefined;
20320
+ }
20313
20321
return undefined;
20314
20322
}
20315
- iteratorMethodSignatures = iteratorMethod && getSignaturesOfType(iteratorMethod, SignatureKind.Call);
20316
- isNonAsyncIterable = true;
20317
- }
20318
20323
20319
- if (some(iteratorMethodSignatures)) {
20320
- const iteratorMethodReturnType = getUnionType(map(iteratorMethodSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
20321
- const iteratedType = getIteratedTypeOfIterator(iteratorMethodReturnType, errorNode, /*isAsyncIterator*/ !isNonAsyncIterable);
20324
+ const returnType = getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
20325
+ const iteratedType = getIteratedTypeOfIterator(returnType, errorNode, /*isAsyncIterator*/ !!asyncMethodType);
20322
20326
if (checkAssignability && errorNode && iteratedType) {
20323
20327
// If `checkAssignability` was specified, we were called from
20324
20328
// `checkIteratedTypeOrElementType`. As such, we need to validate that
20325
20329
// the type passed in is actually an Iterable.
20326
- checkTypeAssignableTo(type, isNonAsyncIterable
20327
- ? createIterableType (iteratedType)
20328
- : createAsyncIterableType (iteratedType), errorNode);
20330
+ checkTypeAssignableTo(type, asyncMethodType
20331
+ ? createAsyncIterableType (iteratedType)
20332
+ : createIterableType (iteratedType), errorNode);
20329
20333
}
20330
- return isAsyncIterable
20334
+
20335
+ return asyncMethodType
20331
20336
? typeAsIterable.iteratedTypeOfAsyncIterable = iteratedType
20332
20337
: typeAsIterable.iteratedTypeOfIterable = iteratedType;
20333
20338
}
20334
-
20335
- if (errorNode) {
20336
- error(errorNode,
20337
- isAsyncIterable
20338
- ? Diagnostics.Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
20339
- : Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator);
20340
- }
20341
-
20342
- return undefined;
20343
20339
}
20344
20340
20345
20341
/**
@@ -20439,7 +20435,7 @@ namespace ts {
20439
20435
return undefined;
20440
20436
}
20441
20437
20442
- return getIteratedTypeOfIterable(returnType, /*errorNode*/ undefined, isAsyncGenerator, /*allowNonAsyncIterables */ false , /*checkAssignability*/ false)
20438
+ return getIteratedTypeOfIterable(returnType, /*errorNode*/ undefined, /*allowAsyncIterables*/ isAsyncGenerator, /*allowSyncIterables */ !isAsyncGenerator , /*checkAssignability*/ false)
20443
20439
|| getIteratedTypeOfIterator(returnType, /*errorNode*/ undefined, isAsyncGenerator);
20444
20440
}
20445
20441
@@ -22649,7 +22645,7 @@ namespace ts {
22649
22645
Debug.assert(expr.parent.kind === SyntaxKind.ArrayLiteralExpression);
22650
22646
// [{ property1: p1, property2 }] = elems;
22651
22647
const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>expr.parent);
22652
- const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterable */ false) || unknownType;
22648
+ const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables */ false) || unknownType;
22653
22649
return checkArrayLiteralDestructuringElementAssignment(<ArrayLiteralExpression>expr.parent, typeOfArrayLiteral,
22654
22650
indexOf((<ArrayLiteralExpression>expr.parent).elements, expr), elementType || unknownType);
22655
22651
}
0 commit comments