@@ -18523,27 +18523,25 @@ namespace ts {
18523
18523
18524
18524
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] {
18525
18525
const aggregatedTypes: Type[] = [];
18526
- const functionFlags = getFunctionFlags(func);
18526
+ const isAsync = ( getFunctionFlags(func) & FunctionFlags.Async) !== 0 ;
18527
18527
forEachYieldExpression(<Block>func.body, yieldExpression => {
18528
- const expr = yieldExpression.expression;
18529
- if (expr) {
18530
- let type = checkExpressionCached(expr, checkMode);
18531
- if (yieldExpression.asteriskToken) {
18532
- // A yield* expression effectively yields everything that its operand yields
18533
- type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & FunctionFlags.Async) !== 0);
18534
- }
18535
- if (functionFlags & FunctionFlags.Async) {
18536
- type = checkAwaitedType(type, expr, yieldExpression.asteriskToken
18537
- ? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
18538
- : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
18539
- }
18540
- pushIfUnique(aggregatedTypes, type);
18528
+ if (yieldExpression.expression) { // TODO: GH#22297
18529
+ pushIfUnique(aggregatedTypes, getYieldedTypeOfYieldExpression(yieldExpression, isAsync, checkMode));
18541
18530
}
18542
18531
});
18543
-
18544
18532
return aggregatedTypes;
18545
18533
}
18546
18534
18535
+ function getYieldedTypeOfYieldExpression(node: YieldExpression, isAsync: boolean, checkMode?: CheckMode): Type {
18536
+ const errorNode = node.expression || node;
18537
+ const expressionType = node.expression ? checkExpressionCached(node.expression, checkMode) : undefinedWideningType;
18538
+ // A `yield*` expression effectively yields everything that its operand yields
18539
+ const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(expressionType, errorNode, /*allowStringInput*/ false, isAsync) : expressionType;
18540
+ return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken
18541
+ ? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
18542
+ : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
18543
+ }
18544
+
18547
18545
function isExhaustiveSwitchStatement(node: SwitchStatement): boolean {
18548
18546
if (!node.possiblyExhaustive) {
18549
18547
return false;
@@ -19499,62 +19497,42 @@ namespace ts {
19499
19497
}
19500
19498
}
19501
19499
19502
- if (node.expression) {
19503
- const func = getContainingFunction(node);
19504
- // If the user's code is syntactically correct, the func should always have a star. After all,
19505
- // we are in a yield context.
19506
- const functionFlags = func && getFunctionFlags(func);
19507
- if (node.asteriskToken) {
19508
- // Async generator functions prior to ESNext require the __await, __asyncDelegator,
19509
- // and __asyncValues helpers
19510
- if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator &&
19511
- languageVersion < ScriptTarget.ESNext) {
19512
- checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegatorIncludes);
19513
- }
19514
-
19515
- // Generator functions prior to ES2015 require the __values helper
19516
- if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Generator &&
19517
- languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
19518
- checkExternalEmitHelpers(node, ExternalEmitHelpers.Values);
19519
- }
19520
- }
19521
-
19522
- if (functionFlags & FunctionFlags.Generator) {
19523
- const expressionType = checkExpressionCached(node.expression);
19524
- let expressionElementType: Type;
19525
- const nodeIsYieldStar = !!node.asteriskToken;
19526
- if (nodeIsYieldStar) {
19527
- expressionElementType = checkIteratedTypeOrElementType(expressionType, node.expression, /*allowStringInput*/ false, (functionFlags & FunctionFlags.Async) !== 0);
19528
- }
19529
-
19530
- // There is no point in doing an assignability check if the function
19531
- // has no explicit return type because the return type is directly computed
19532
- // from the yield expressions.
19533
- const returnType = getEffectiveReturnTypeNode(func);
19534
- if (returnType) {
19535
- const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & FunctionFlags.Async) !== 0) || anyType;
19536
- if (nodeIsYieldStar) {
19537
- checkTypeAssignableTo(
19538
- functionFlags & FunctionFlags.Async
19539
- ? 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)
19540
- : expressionElementType,
19541
- signatureElementType,
19542
- node.expression,
19543
- /*headMessage*/ undefined);
19544
- }
19545
- else {
19546
- checkTypeAssignableTo(
19547
- functionFlags & FunctionFlags.Async
19548
- ? 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)
19549
- : expressionType,
19550
- signatureElementType,
19551
- node.expression,
19552
- /*headMessage*/ undefined);
19553
- }
19554
- }
19500
+ const func = getContainingFunction(node);
19501
+ const functionFlags = func ? getFunctionFlags(func) : FunctionFlags.Normal;
19502
+
19503
+ if (!(functionFlags & FunctionFlags.Generator)) {
19504
+ // If the user's code is syntactically correct, the func should always have a star. After all, we are in a yield context.
19505
+ return anyType;
19506
+ }
19507
+
19508
+ if (node.asteriskToken) {
19509
+ // Async generator functions prior to ESNext require the __await, __asyncDelegator,
19510
+ // and __asyncValues helpers
19511
+ if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator &&
19512
+ languageVersion < ScriptTarget.ESNext) {
19513
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegatorIncludes);
19514
+ }
19515
+
19516
+ // Generator functions prior to ES2015 require the __values helper
19517
+ if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Generator &&
19518
+ languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
19519
+ checkExternalEmitHelpers(node, ExternalEmitHelpers.Values);
19555
19520
}
19556
19521
}
19557
19522
19523
+ if (!node.expression) return anyType; // TODO: GH#22297
19524
+
19525
+ const isAsync = (functionFlags & FunctionFlags.Async) !== 0;
19526
+ const yieldedType = getYieldedTypeOfYieldExpression(node, isAsync);
19527
+ // There is no point in doing an assignability check if the function
19528
+ // has no explicit return type because the return type is directly computed
19529
+ // from the yield expressions.
19530
+ const returnType = getEffectiveReturnTypeNode(func);
19531
+ if (returnType) {
19532
+ const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), isAsync) || anyType;
19533
+ checkTypeAssignableTo(yieldedType, signatureElementType, node.expression || node, /*headMessage*/ undefined);
19534
+ }
19535
+
19558
19536
// Both yield and yield* expressions have type 'any'
19559
19537
return anyType;
19560
19538
}
0 commit comments