Skip to content

Commit 48fc6b8

Browse files
committed
Did you forget to use await? on iterables
1 parent c48e34e commit 48fc6b8

File tree

3 files changed

+46
-17
lines changed

3 files changed

+46
-17
lines changed

src/compiler/checker.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27922,18 +27922,28 @@ namespace ts {
2792227922
// number and string input is allowed, we want to say that number is not an
2792327923
// array type or a string type.
2792427924
const yieldType = getIterationTypeOfIterable(use, IterationTypeKind.Yield, inputType, /*errorNode*/ undefined);
27925-
const diagnostic = !(use & IterationUse.AllowsStringInputFlag) || hasStringConstituent
27925+
const [defaultDiagnostic, missingAwaitDiagnostic]: [DiagnosticMessage, DiagnosticMessage | undefined] = !(use & IterationUse.AllowsStringInputFlag) || hasStringConstituent
2792627926
? downlevelIteration
27927-
? Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
27927+
? [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_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await]
2792827928
: yieldType
27929-
? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators
27930-
: Diagnostics.Type_0_is_not_an_array_type
27929+
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined]
27930+
: [Diagnostics.Type_0_is_not_an_array_type, Diagnostics.Type_0_is_not_an_array_type_Did_you_forget_to_use_await]
2793127931
: downlevelIteration
27932-
? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator
27932+
? [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_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await]
2793327933
: yieldType
27934-
? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators
27935-
: Diagnostics.Type_0_is_not_an_array_type_or_a_string_type;
27936-
error(errorNode, diagnostic, typeToString(arrayType));
27934+
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined]
27935+
: [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Did_you_forget_to_use_await];
27936+
if (missingAwaitDiagnostic) {
27937+
errorAndMaybeSuggestAwait(
27938+
errorNode,
27939+
!!getAwaitedTypeOfPromise(arrayType),
27940+
defaultDiagnostic,
27941+
missingAwaitDiagnostic,
27942+
typeToString(arrayType));
27943+
}
27944+
else {
27945+
error(errorNode, defaultDiagnostic, typeToString(arrayType));
27946+
}
2793727947
}
2793827948
return hasStringConstituent ? stringType : undefined;
2793927949
}
@@ -28232,9 +28242,10 @@ namespace ts {
2823228242
}
2823328243

2823428244
function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void {
28235-
error(errorNode, allowAsyncIterables
28236-
? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
28237-
: Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, typeToString(type));
28245+
const [defaultDiagnostic, missingAwaitDiagnostic] = allowAsyncIterables
28246+
? [Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator, Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_Did_you_forget_to_use_await]
28247+
: [Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await];
28248+
errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), defaultDiagnostic, missingAwaitDiagnostic, typeToString(type));
2823828249
}
2823928250

2824028251
/**

src/compiler/diagnosticMessages.json

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,26 +2713,42 @@
27132713
"category": "Error",
27142714
"code": 2777
27152715
},
2716-
"Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": {
2716+
"Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'?": {
27172717
"category": "Error",
27182718
"code": 2778
27192719
},
2720-
"Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": {
2720+
"Type '{0}' is not an array type. Did you forget to use 'await'?": {
27212721
"category": "Error",
27222722
"code": 2779
27232723
},
2724-
"Type '{0}' has no call signatures. Did you forget to use 'await'?": {
2724+
"Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": {
27252725
"category": "Error",
27262726
"code": 2780
27272727
},
2728-
"Type '{0}' has no construct signatures. Did you forget to use 'await'?": {
2728+
"Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": {
27292729
"category": "Error",
27302730
"code": 2781
27312731
},
2732-
"This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": {
2732+
"Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": {
27332733
"category": "Error",
27342734
"code": 2782
27352735
},
2736+
"Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": {
2737+
"category": "Error",
2738+
"code": 2783
2739+
},
2740+
"Type '{0}' has no call signatures. Did you forget to use 'await'?": {
2741+
"category": "Error",
2742+
"code": 2784
2743+
},
2744+
"Type '{0}' has no construct signatures. Did you forget to use 'await'?": {
2745+
"category": "Error",
2746+
"code": 2785
2747+
},
2748+
"This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": {
2749+
"category": "Error",
2750+
"code": 2786
2751+
},
27362752

27372753
"Import declaration '{0}' is using private name '{1}'.": {
27382754
"category": "Error",

tests/cases/compiler/operationsAvailableOnPromisedType.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function fn(
1+
async function fn(
22
a: number,
33
b: Promise<number>,
44
c: Promise<string[]>,
@@ -15,10 +15,12 @@ function fn(
1515
b++;
1616
--b;
1717
a === b;
18+
[...c];
1819
for (const s of c) {
1920
fn(b, b, c, d);
2021
d.prop;
2122
}
23+
for await (const s of c) {}
2224
e();
2325
f();
2426
new g();

0 commit comments

Comments
 (0)