@@ -842,6 +842,7 @@ namespace ts {
842842 let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined;
843843 let deferredGlobalESSymbolType: ObjectType;
844844 let deferredGlobalTypedPropertyDescriptorType: GenericType;
845+ let deferredGlobalAwaitedSymbol: Symbol | undefined;
845846 let deferredGlobalPromiseType: GenericType;
846847 let deferredGlobalPromiseLikeType: GenericType;
847848 let deferredGlobalPromiseConstructorSymbol: Symbol | undefined;
@@ -896,7 +897,6 @@ namespace ts {
896897 const potentialThisCollisions: Node[] = [];
897898 const potentialNewTargetCollisions: Node[] = [];
898899 const potentialWeakMapCollisions: Node[] = [];
899- const awaitedTypeStack: number[] = [];
900900
901901 const diagnostics = createDiagnosticCollection();
902902 const suggestionDiagnostics = createDiagnosticCollection();
@@ -11455,6 +11455,10 @@ namespace ts {
1145511455 return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
1145611456 }
1145711457
11458+ function getGlobalAwaitedSymbol(reportErrors: boolean) {
11459+ return deferredGlobalAwaitedSymbol || (deferredGlobalAwaitedSymbol = getGlobalTypeSymbol("Awaited" as __String, reportErrors));
11460+ }
11461+
1145811462 function getGlobalPromiseType(reportErrors: boolean) {
1145911463 return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
1146011464 }
@@ -26272,8 +26276,6 @@ namespace ts {
2627226276 // creates a `Promise<T>` type where `T` is the promisedType argument
2627326277 const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
2627426278 if (globalPromiseType !== emptyGenericType) {
26275- // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
26276- promisedType = getAwaitedType(promisedType) || unknownType;
2627726279 return createTypeReference(globalPromiseType, [promisedType]);
2627826280 }
2627926281
@@ -26284,8 +26286,6 @@ namespace ts {
2628426286 // creates a `PromiseLike<T>` type where `T` is the promisedType argument
2628526287 const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
2628626288 if (globalPromiseLikeType !== emptyGenericType) {
26287- // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
26288- promisedType = getAwaitedType(promisedType) || unknownType;
2628926289 return createTypeReference(globalPromiseLikeType, [promisedType]);
2629026290 }
2629126291
@@ -29746,98 +29746,26 @@ namespace ts {
2974629746 return typeAsAwaitable.awaitedTypeOfType = type;
2974729747 }
2974829748
29749- if (type.flags & TypeFlags.Union) {
29750- let types: Type[] | undefined;
29751- for (const constituentType of (<UnionType>type).types) {
29752- types = append<Type>(types, getAwaitedType(constituentType, errorNode, diagnosticMessage, arg0));
29753- }
29754-
29755- if (!types) {
29756- return undefined;
29757- }
29758-
29759- return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
29749+ const symbol = getGlobalAwaitedSymbol(/*reportErrors*/ false);
29750+ if (!symbol) {
29751+ return typeAsAwaitable.awaitedTypeOfType = type;
2976029752 }
2976129753
29762- const promisedType = getPromisedTypeOfPromise(type);
29763- if (promisedType) {
29764- if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
29765- // Verify that we don't have a bad actor in the form of a promise whose
29766- // promised type is the same as the promise type, or a mutually recursive
29767- // promise. If so, we return undefined as we cannot guess the shape. If this
29768- // were the actual case in the JavaScript, this Promise would never resolve.
29769- //
29770- // An example of a bad actor with a singly-recursive promise type might
29771- // be:
29772- //
29773- // interface BadPromise {
29774- // then(
29775- // onfulfilled: (value: BadPromise) => any,
29776- // onrejected: (error: any) => any): BadPromise;
29777- // }
29778- // The above interface will pass the PromiseLike check, and return a
29779- // promised type of `BadPromise`. Since this is a self reference, we
29780- // don't want to keep recursing ad infinitum.
29781- //
29782- // An example of a bad actor in the form of a mutually-recursive
29783- // promise type might be:
29784- //
29785- // interface BadPromiseA {
29786- // then(
29787- // onfulfilled: (value: BadPromiseB) => any,
29788- // onrejected: (error: any) => any): BadPromiseB;
29789- // }
29790- //
29791- // interface BadPromiseB {
29792- // then(
29793- // onfulfilled: (value: BadPromiseA) => any,
29794- // onrejected: (error: any) => any): BadPromiseA;
29795- // }
29796- //
29797- if (errorNode) {
29798- error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
29799- }
29800- return undefined;
29801- }
29802-
29803- // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
29804- // See the comments above for more information.
29805- awaitedTypeStack.push(type.id);
29806- const awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
29807- awaitedTypeStack.pop();
29808-
29809- if (!awaitedType) {
29810- return undefined;
29811- }
29754+ if (type.aliasSymbol === symbol) {
29755+ return typeAsAwaitable.awaitedTypeOfType = type;
29756+ }
2981229757
29813- return typeAsAwaitable.awaitedTypeOfType = awaitedType;
29758+ const result = getTypeAliasInstantiation(symbol, [type]);
29759+ if (result !== unknownType || type === unknownType || getPromisedTypeOfPromise(type) === unknownType) {
29760+ return typeAsAwaitable.awaitedTypeOfType = result;
2981429761 }
2981529762
29816- // The type was not a promise, so it could not be unwrapped any further.
29817- // As long as the type does not have a callable "then" property, it is
29818- // safe to return the type; otherwise, an error will be reported in
29819- // the call to getNonThenableType and we will return undefined.
29820- //
29821- // An example of a non-promise "thenable" might be:
29822- //
29823- // await { then(): void {} }
29824- //
29825- // The "thenable" does not match the minimal definition for a promise. When
29826- // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
29827- // will never settle. We treat this as an error to help flag an early indicator
29828- // of a runtime problem. If the user wants to return this value from an async
29829- // function, they would need to wrap it in some other value. If they want it to
29830- // be treated as a promise, they can cast to <any>.
29831- const thenFunction = getTypeOfPropertyOfType(type, "then" as __String);
29832- if (thenFunction && getSignaturesOfType(thenFunction, SignatureKind.Call).length > 0) {
29833- if (errorNode) {
29834- if (!diagnosticMessage) return Debug.fail();
29835- error(errorNode, diagnosticMessage, arg0);
29836- }
29837- return undefined;
29763+ if (errorNode) {
29764+ if (!diagnosticMessage) return Debug.fail();
29765+ error(errorNode, diagnosticMessage, arg0);
2983829766 }
2983929767
29840- return typeAsAwaitable.awaitedTypeOfType = type ;
29768+ return undefined ;
2984129769 }
2984229770
2984329771 /**
0 commit comments