@@ -820,6 +820,7 @@ namespace ts {
820
820
let deferredGlobalESSymbolConstructorSymbol: Symbol | undefined;
821
821
let deferredGlobalESSymbolType: ObjectType;
822
822
let deferredGlobalTypedPropertyDescriptorType: GenericType;
823
+ let deferredGlobalAwaitedSymbol: Symbol | undefined;
823
824
let deferredGlobalPromiseType: GenericType;
824
825
let deferredGlobalPromiseLikeType: GenericType;
825
826
let deferredGlobalPromiseConstructorSymbol: Symbol | undefined;
@@ -874,7 +875,6 @@ namespace ts {
874
875
const potentialThisCollisions: Node[] = [];
875
876
const potentialNewTargetCollisions: Node[] = [];
876
877
const potentialWeakMapCollisions: Node[] = [];
877
- const awaitedTypeStack: number[] = [];
878
878
879
879
const diagnostics = createDiagnosticCollection();
880
880
const suggestionDiagnostics = createDiagnosticCollection();
@@ -11309,6 +11309,10 @@ namespace ts {
11309
11309
return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
11310
11310
}
11311
11311
11312
+ function getGlobalAwaitedSymbol(reportErrors: boolean) {
11313
+ return deferredGlobalAwaitedSymbol || (deferredGlobalAwaitedSymbol = getGlobalTypeSymbol("Awaited" as __String, reportErrors));
11314
+ }
11315
+
11312
11316
function getGlobalPromiseType(reportErrors: boolean) {
11313
11317
return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
11314
11318
}
@@ -26053,8 +26057,6 @@ namespace ts {
26053
26057
// creates a `Promise<T>` type where `T` is the promisedType argument
26054
26058
const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
26055
26059
if (globalPromiseType !== emptyGenericType) {
26056
- // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
26057
- promisedType = getAwaitedType(promisedType) || unknownType;
26058
26060
return createTypeReference(globalPromiseType, [promisedType]);
26059
26061
}
26060
26062
@@ -26065,8 +26067,6 @@ namespace ts {
26065
26067
// creates a `PromiseLike<T>` type where `T` is the promisedType argument
26066
26068
const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
26067
26069
if (globalPromiseLikeType !== emptyGenericType) {
26068
- // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
26069
- promisedType = getAwaitedType(promisedType) || unknownType;
26070
26070
return createTypeReference(globalPromiseLikeType, [promisedType]);
26071
26071
}
26072
26072
@@ -29528,98 +29528,26 @@ namespace ts {
29528
29528
return typeAsAwaitable.awaitedTypeOfType = type;
29529
29529
}
29530
29530
29531
- if (type.flags & TypeFlags.Union) {
29532
- let types: Type[] | undefined;
29533
- for (const constituentType of (<UnionType>type).types) {
29534
- types = append<Type>(types, getAwaitedType(constituentType, errorNode, diagnosticMessage, arg0));
29535
- }
29536
-
29537
- if (!types) {
29538
- return undefined;
29539
- }
29540
-
29541
- return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
29531
+ const symbol = getGlobalAwaitedSymbol(/*reportErrors*/ false);
29532
+ if (!symbol) {
29533
+ return typeAsAwaitable.awaitedTypeOfType = type;
29542
29534
}
29543
29535
29544
- const promisedType = getPromisedTypeOfPromise(type);
29545
- if (promisedType) {
29546
- if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
29547
- // Verify that we don't have a bad actor in the form of a promise whose
29548
- // promised type is the same as the promise type, or a mutually recursive
29549
- // promise. If so, we return undefined as we cannot guess the shape. If this
29550
- // were the actual case in the JavaScript, this Promise would never resolve.
29551
- //
29552
- // An example of a bad actor with a singly-recursive promise type might
29553
- // be:
29554
- //
29555
- // interface BadPromise {
29556
- // then(
29557
- // onfulfilled: (value: BadPromise) => any,
29558
- // onrejected: (error: any) => any): BadPromise;
29559
- // }
29560
- // The above interface will pass the PromiseLike check, and return a
29561
- // promised type of `BadPromise`. Since this is a self reference, we
29562
- // don't want to keep recursing ad infinitum.
29563
- //
29564
- // An example of a bad actor in the form of a mutually-recursive
29565
- // promise type might be:
29566
- //
29567
- // interface BadPromiseA {
29568
- // then(
29569
- // onfulfilled: (value: BadPromiseB) => any,
29570
- // onrejected: (error: any) => any): BadPromiseB;
29571
- // }
29572
- //
29573
- // interface BadPromiseB {
29574
- // then(
29575
- // onfulfilled: (value: BadPromiseA) => any,
29576
- // onrejected: (error: any) => any): BadPromiseA;
29577
- // }
29578
- //
29579
- if (errorNode) {
29580
- error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
29581
- }
29582
- return undefined;
29583
- }
29584
-
29585
- // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
29586
- // See the comments above for more information.
29587
- awaitedTypeStack.push(type.id);
29588
- const awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
29589
- awaitedTypeStack.pop();
29590
-
29591
- if (!awaitedType) {
29592
- return undefined;
29593
- }
29536
+ if (type.aliasSymbol === symbol) {
29537
+ return typeAsAwaitable.awaitedTypeOfType = type;
29538
+ }
29594
29539
29595
- return typeAsAwaitable.awaitedTypeOfType = awaitedType;
29540
+ const result = getTypeAliasInstantiation(symbol, [type]);
29541
+ if (result !== unknownType || type === unknownType || getPromisedTypeOfPromise(type) === unknownType) {
29542
+ return typeAsAwaitable.awaitedTypeOfType = result;
29596
29543
}
29597
29544
29598
- // The type was not a promise, so it could not be unwrapped any further.
29599
- // As long as the type does not have a callable "then" property, it is
29600
- // safe to return the type; otherwise, an error will be reported in
29601
- // the call to getNonThenableType and we will return undefined.
29602
- //
29603
- // An example of a non-promise "thenable" might be:
29604
- //
29605
- // await { then(): void {} }
29606
- //
29607
- // The "thenable" does not match the minimal definition for a promise. When
29608
- // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
29609
- // will never settle. We treat this as an error to help flag an early indicator
29610
- // of a runtime problem. If the user wants to return this value from an async
29611
- // function, they would need to wrap it in some other value. If they want it to
29612
- // be treated as a promise, they can cast to <any>.
29613
- const thenFunction = getTypeOfPropertyOfType(type, "then" as __String);
29614
- if (thenFunction && getSignaturesOfType(thenFunction, SignatureKind.Call).length > 0) {
29615
- if (errorNode) {
29616
- if (!diagnosticMessage) return Debug.fail();
29617
- error(errorNode, diagnosticMessage, arg0);
29618
- }
29619
- return undefined;
29545
+ if (errorNode) {
29546
+ if (!diagnosticMessage) return Debug.fail();
29547
+ error(errorNode, diagnosticMessage, arg0);
29620
29548
}
29621
29549
29622
- return typeAsAwaitable.awaitedTypeOfType = type ;
29550
+ return undefined ;
29623
29551
}
29624
29552
29625
29553
/**
0 commit comments