@@ -18380,27 +18380,23 @@ namespace ts {
18380
18380
18381
18381
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] {
18382
18382
const aggregatedTypes: Type[] = [];
18383
- const functionFlags = getFunctionFlags(func);
18383
+ const isAsync = ( getFunctionFlags(func) & FunctionFlags.Async) !== 0 ;
18384
18384
forEachYieldExpression(<Block>func.body, yieldExpression => {
18385
- const expr = yieldExpression.expression;
18386
- if (expr) {
18387
- let type = checkExpressionCached(expr, checkMode);
18388
- if (yieldExpression.asteriskToken) {
18389
- // A yield* expression effectively yields everything that its operand yields
18390
- type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & FunctionFlags.Async) !== 0);
18391
- }
18392
- if (functionFlags & FunctionFlags.Async) {
18393
- type = checkAwaitedType(type, expr, yieldExpression.asteriskToken
18394
- ? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
18395
- : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
18396
- }
18397
- pushIfUnique(aggregatedTypes, type);
18398
- }
18385
+ pushIfUnique(aggregatedTypes, getYieldedTypeOfYieldExpression(yieldExpression, isAsync, checkMode));
18399
18386
});
18400
-
18401
18387
return aggregatedTypes;
18402
18388
}
18403
18389
18390
+ function getYieldedTypeOfYieldExpression(node: YieldExpression, isAsync: boolean, checkMode?: CheckMode): Type {
18391
+ const errorNode = node.expression || node;
18392
+ const expressionType = node.expression ? checkExpressionCached(node.expression, checkMode) : undefinedType;
18393
+ // A yield* expression effectively yields everything that its operand yields
18394
+ const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(expressionType, errorNode, /*allowStringInput*/ false, isAsync) : expressionType;
18395
+ return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken
18396
+ ? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
18397
+ : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
18398
+ }
18399
+
18404
18400
function isExhaustiveSwitchStatement(node: SwitchStatement): boolean {
18405
18401
if (!node.possiblyExhaustive) {
18406
18402
return false;
@@ -19353,62 +19349,40 @@ namespace ts {
19353
19349
}
19354
19350
}
19355
19351
19356
- if (node.expression) {
19357
- const func = getContainingFunction(node);
19358
- // If the user's code is syntactically correct, the func should always have a star. After all,
19359
- // we are in a yield context.
19360
- const functionFlags = func && getFunctionFlags(func);
19361
- if (node.asteriskToken) {
19362
- // Async generator functions prior to ESNext require the __await, __asyncDelegator,
19363
- // and __asyncValues helpers
19364
- if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator &&
19365
- languageVersion < ScriptTarget.ESNext) {
19366
- checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegatorIncludes);
19367
- }
19368
-
19369
- // Generator functions prior to ES2015 require the __values helper
19370
- if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Generator &&
19371
- languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
19372
- checkExternalEmitHelpers(node, ExternalEmitHelpers.Values);
19373
- }
19374
- }
19375
-
19376
- if (functionFlags & FunctionFlags.Generator) {
19377
- const expressionType = checkExpressionCached(node.expression);
19378
- let expressionElementType: Type;
19379
- const nodeIsYieldStar = !!node.asteriskToken;
19380
- if (nodeIsYieldStar) {
19381
- expressionElementType = checkIteratedTypeOrElementType(expressionType, node.expression, /*allowStringInput*/ false, (functionFlags & FunctionFlags.Async) !== 0);
19382
- }
19383
-
19384
- // There is no point in doing an assignability check if the function
19385
- // has no explicit return type because the return type is directly computed
19386
- // from the yield expressions.
19387
- const returnType = getEffectiveReturnTypeNode(func);
19388
- if (returnType) {
19389
- const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & FunctionFlags.Async) !== 0) || anyType;
19390
- if (nodeIsYieldStar) {
19391
- checkTypeAssignableTo(
19392
- functionFlags & FunctionFlags.Async
19393
- ? getAwaitedType(expressionElementType, node.expression, Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
19394
- : expressionElementType,
19395
- signatureElementType,
19396
- node.expression,
19397
- /*headMessage*/ undefined);
19398
- }
19399
- else {
19400
- checkTypeAssignableTo(
19401
- functionFlags & FunctionFlags.Async
19402
- ? getAwaitedType(expressionType, node.expression, Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
19403
- : expressionType,
19404
- signatureElementType,
19405
- node.expression,
19406
- /*headMessage*/ undefined);
19407
- }
19408
- }
19352
+ const func = getContainingFunction(node);
19353
+ const functionFlags = func ? getFunctionFlags(func) : FunctionFlags.Normal;
19354
+
19355
+ if (!(functionFlags & FunctionFlags.Generator)) {
19356
+ // If the user's code is syntactically correct, the func should always have a star. After all, we are in a yield context.
19357
+ return anyType;
19358
+ }
19359
+
19360
+ if (node.asteriskToken) {
19361
+ // Async generator functions prior to ESNext require the __await, __asyncDelegator,
19362
+ // and __asyncValues helpers
19363
+ if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator &&
19364
+ languageVersion < ScriptTarget.ESNext) {
19365
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegatorIncludes);
19366
+ }
19367
+
19368
+ // Generator functions prior to ES2015 require the __values helper
19369
+ if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Generator &&
19370
+ languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
19371
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Values);
19409
19372
}
19410
19373
}
19411
19374
19375
+ const isAsync = (functionFlags & FunctionFlags.Async) !== 0;
19376
+ const yieldedType = getYieldedTypeOfYieldExpression(node, isAsync);
19377
+ // There is no point in doing an assignability check if the function
19378
+ // has no explicit return type because the return type is directly computed
19379
+ // from the yield expressions.
19380
+ const returnType = getEffectiveReturnTypeNode(func);
19381
+ if (returnType) {
19382
+ const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), isAsync) || anyType;
19383
+ checkTypeAssignableTo(yieldedType, signatureElementType, node.expression || node, /*headMessage*/ undefined);
19384
+ }
19385
+
19412
19386
// Both yield and yield* expressions have type 'any'
19413
19387
return anyType;
19414
19388
}
0 commit comments