@@ -800,6 +800,7 @@ namespace ts {
800800 let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined;
801801 let deferredGlobalESSymbolType: ObjectType;
802802 let deferredGlobalTypedPropertyDescriptorType: GenericType;
803+ let deferredGlobalAwaitedSymbol: Symbol | undefined;
803804 let deferredGlobalPromiseType: GenericType;
804805 let deferredGlobalPromiseLikeType: GenericType;
805806 let deferredGlobalPromiseConstructorSymbol: Symbol | undefined;
@@ -853,7 +854,6 @@ namespace ts {
853854 const flowNodeReachable: (boolean | undefined)[] = [];
854855 const potentialThisCollisions: Node[] = [];
855856 const potentialNewTargetCollisions: Node[] = [];
856- const awaitedTypeStack: number[] = [];
857857
858858 const diagnostics = createDiagnosticCollection();
859859 const suggestionDiagnostics = createDiagnosticCollection();
@@ -11059,6 +11059,10 @@ namespace ts {
1105911059 return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
1106011060 }
1106111061
11062+ function getGlobalAwaitedSymbol(reportErrors: boolean) {
11063+ return deferredGlobalAwaitedSymbol || (deferredGlobalAwaitedSymbol = getGlobalTypeSymbol("Awaited" as __String, reportErrors));
11064+ }
11065+
1106211066 function getGlobalPromiseType(reportErrors: boolean) {
1106311067 return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
1106411068 }
@@ -25719,7 +25723,7 @@ namespace ts {
2571925723 // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
2572025724 // return type of the body should be unwrapped to its awaited type, which we will wrap in
2572125725 // the native Promise<T> type later in this function.
25722- returnType = checkAwaitedType(returnType, /*errorNode*/ func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member );
25726+ returnType = checkAwaitedType(returnType);
2572325727 }
2572425728 }
2572525729 else if (isGenerator) { // Generator or AsyncGenerator function
@@ -25858,9 +25862,7 @@ namespace ts {
2585825862 const errorNode = node.expression || node;
2585925863 // A `yield*` expression effectively yields everything that its operand yields
2586025864 const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(isAsync ? IterationUse.AsyncYieldStar : IterationUse.YieldStar, expressionType, sentType, errorNode) : expressionType;
25861- return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken
25862- ? Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
25863- : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
25865+ return !isAsync ? yieldedType : getAwaitedType(yieldedType);
2586425866 }
2586525867
2586625868 /**
@@ -25951,7 +25953,7 @@ namespace ts {
2595125953 // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
2595225954 // return type of the body should be unwrapped to its awaited type, which should be wrapped in
2595325955 // the native Promise<T> type by the caller.
25954- type = checkAwaitedType(type, func, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member );
25956+ type = checkAwaitedType(type);
2595525957 }
2595625958 if (type.flags & TypeFlags.Never) {
2595725959 hasReturnOfTypeNever = true;
@@ -26155,7 +26157,7 @@ namespace ts {
2615526157 const returnOrPromisedType = getReturnOrPromisedType(returnType, functionFlags);
2615626158 if (returnOrPromisedType) {
2615726159 if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function
26158- const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member );
26160+ const awaitedType = checkAwaitedType(exprType);
2615926161 checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body);
2616026162 }
2616126163 else { // Normal function
@@ -26324,7 +26326,7 @@ namespace ts {
2632426326 }
2632526327
2632626328 const operandType = checkExpression(node.expression);
26327- const awaitedType = checkAwaitedType(operandType, node, Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member );
26329+ const awaitedType = checkAwaitedType(operandType);
2632826330 if (awaitedType === operandType && awaitedType !== errorType && !(operandType.flags & TypeFlags.AnyOrUnknown)) {
2632926331 addErrorOrSuggestion(/*isError*/ false, createDiagnosticForNode(node, Diagnostics.await_has_no_effect_on_the_type_of_this_expression));
2633026332 }
@@ -28830,9 +28832,9 @@ namespace ts {
2883028832 }
2883128833 }
2883228834
28833- function getAwaitedTypeOfPromise(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number ): Type | undefined {
28835+ function getAwaitedTypeOfPromise(type: Type, errorNode?: Node): Type | undefined {
2883428836 const promisedType = getPromisedTypeOfPromise(type, errorNode);
28835- return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0 );
28837+ return promisedType && getAwaitedType(promisedType);
2883628838 }
2883728839
2883828840 /**
@@ -28900,12 +28902,12 @@ namespace ts {
2890028902 * Promise-like type; otherwise, it is the type of the expression. This is used to reflect
2890128903 * The runtime behavior of the `await` keyword.
2890228904 */
28903- function checkAwaitedType(type: Type, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number ): Type {
28904- const awaitedType = getAwaitedType(type, errorNode, diagnosticMessage, arg0 );
28905+ function checkAwaitedType(type: Type): Type {
28906+ const awaitedType = getAwaitedType(type);
2890528907 return awaitedType || errorType;
2890628908 }
2890728909
28908- function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number ): Type | undefined {
28910+ function getAwaitedType(type: Type): Type | undefined {
2890928911 const typeAsAwaitable = <PromiseOrAwaitableType>type;
2891028912 if (typeAsAwaitable.awaitedTypeOfType) {
2891128913 return typeAsAwaitable.awaitedTypeOfType;
@@ -28915,95 +28917,10 @@ namespace ts {
2891528917 return typeAsAwaitable.awaitedTypeOfType = type;
2891628918 }
2891728919
28918- if (type.flags & TypeFlags.Union) {
28919- let types: Type[] | undefined;
28920- for (const constituentType of (<UnionType>type).types) {
28921- types = append<Type>(types, getAwaitedType(constituentType, errorNode, diagnosticMessage, arg0));
28922- }
28923-
28924- if (!types) {
28925- return undefined;
28926- }
28927-
28928- return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
28929- }
28930-
28931- const promisedType = getPromisedTypeOfPromise(type);
28932- if (promisedType) {
28933- if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
28934- // Verify that we don't have a bad actor in the form of a promise whose
28935- // promised type is the same as the promise type, or a mutually recursive
28936- // promise. If so, we return undefined as we cannot guess the shape. If this
28937- // were the actual case in the JavaScript, this Promise would never resolve.
28938- //
28939- // An example of a bad actor with a singly-recursive promise type might
28940- // be:
28941- //
28942- // interface BadPromise {
28943- // then(
28944- // onfulfilled: (value: BadPromise) => any,
28945- // onrejected: (error: any) => any): BadPromise;
28946- // }
28947- // The above interface will pass the PromiseLike check, and return a
28948- // promised type of `BadPromise`. Since this is a self reference, we
28949- // don't want to keep recursing ad infinitum.
28950- //
28951- // An example of a bad actor in the form of a mutually-recursive
28952- // promise type might be:
28953- //
28954- // interface BadPromiseA {
28955- // then(
28956- // onfulfilled: (value: BadPromiseB) => any,
28957- // onrejected: (error: any) => any): BadPromiseB;
28958- // }
28959- //
28960- // interface BadPromiseB {
28961- // then(
28962- // onfulfilled: (value: BadPromiseA) => any,
28963- // onrejected: (error: any) => any): BadPromiseA;
28964- // }
28965- //
28966- if (errorNode) {
28967- error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
28968- }
28969- return undefined;
28970- }
28971-
28972- // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
28973- // See the comments above for more information.
28974- awaitedTypeStack.push(type.id);
28975- const awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
28976- awaitedTypeStack.pop();
28977-
28978- if (!awaitedType) {
28979- return undefined;
28980- }
28981-
28982- return typeAsAwaitable.awaitedTypeOfType = awaitedType;
28983- }
28984-
28985- // The type was not a promise, so it could not be unwrapped any further.
28986- // As long as the type does not have a callable "then" property, it is
28987- // safe to return the type; otherwise, an error will be reported in
28988- // the call to getNonThenableType and we will return undefined.
28989- //
28990- // An example of a non-promise "thenable" might be:
28991- //
28992- // await { then(): void {} }
28993- //
28994- // The "thenable" does not match the minimal definition for a promise. When
28995- // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
28996- // will never settle. We treat this as an error to help flag an early indicator
28997- // of a runtime problem. If the user wants to return this value from an async
28998- // function, they would need to wrap it in some other value. If they want it to
28999- // be treated as a promise, they can cast to <any>.
29000- const thenFunction = getTypeOfPropertyOfType(type, "then" as __String);
29001- if (thenFunction && getSignaturesOfType(thenFunction, SignatureKind.Call).length > 0) {
29002- if (errorNode) {
29003- if (!diagnosticMessage) return Debug.fail();
29004- error(errorNode, diagnosticMessage, arg0);
29005- }
29006- return undefined;
28920+ const symbol = getGlobalAwaitedSymbol(/*reportErrors*/ false);
28921+ if (symbol) {
28922+ const result = getTypeAliasInstantiation(symbol, [type]) as PromiseOrAwaitableType;
28923+ return typeAsAwaitable.awaitedTypeOfType = result.awaitedTypeOfType = result;
2900728924 }
2900828925
2900928926 return typeAsAwaitable.awaitedTypeOfType = type;
@@ -29109,7 +29026,7 @@ namespace ts {
2910929026 return;
2911029027 }
2911129028 }
29112- checkAwaitedType(returnType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member );
29029+ checkAwaitedType(returnType);
2911329030 }
2911429031
2911529032 /** Check a decorator */
@@ -30699,13 +30616,13 @@ namespace ts {
3069930616 return iterationTypes === noIterationTypes ? undefined : iterationTypes;
3070030617 }
3070130618
30702- function getAsyncFromSyncIterationTypes(iterationTypes: IterationTypes, errorNode: Node | undefined ) {
30619+ function getAsyncFromSyncIterationTypes(iterationTypes: IterationTypes) {
3070330620 if (iterationTypes === noIterationTypes) return noIterationTypes;
3070430621 if (iterationTypes === anyIterationTypes) return anyIterationTypes;
3070530622 const { yieldType, returnType, nextType } = iterationTypes;
3070630623 return createIterationTypes(
30707- getAwaitedType(yieldType, errorNode ) || anyType,
30708- getAwaitedType(returnType, errorNode ) || anyType,
30624+ getAwaitedType(yieldType) || anyType,
30625+ getAwaitedType(returnType) || anyType,
3070930626 nextType);
3071030627 }
3071130628
@@ -30741,7 +30658,7 @@ namespace ts {
3074130658 if (use & IterationUse.AllowsAsyncIterablesFlag) {
3074230659 // for a sync iterable in an async context, only use the cached types if they are valid.
3074330660 if (iterationTypes !== noIterationTypes) {
30744- return (type as IterableOrIteratorType).iterationTypesOfAsyncIterable = getAsyncFromSyncIterationTypes(iterationTypes, errorNode );
30661+ return (type as IterableOrIteratorType).iterationTypesOfAsyncIterable = getAsyncFromSyncIterationTypes(iterationTypes);
3074530662 }
3074630663 }
3074730664 else {
@@ -30762,7 +30679,7 @@ namespace ts {
3076230679 if (iterationTypes !== noIterationTypes) {
3076330680 if (use & IterationUse.AllowsAsyncIterablesFlag) {
3076430681 return (type as IterableOrIteratorType).iterationTypesOfAsyncIterable = iterationTypes
30765- ? getAsyncFromSyncIterationTypes(iterationTypes, errorNode )
30682+ ? getAsyncFromSyncIterationTypes(iterationTypes)
3076630683 : noIterationTypes;
3076730684 }
3076830685 else {
@@ -31170,7 +31087,7 @@ namespace ts {
3117031087 else if (getReturnTypeFromAnnotation(func)) {
3117131088 const unwrappedReturnType = unwrapReturnType(returnType, functionFlags);
3117231089 const unwrappedExprType = functionFlags & FunctionFlags.Async
31173- ? checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member )
31090+ ? checkAwaitedType(exprType)
3117431091 : exprType;
3117531092 if (unwrappedReturnType) {
3117631093 // If the function has a return type, but promisedType is
0 commit comments