@@ -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();
@@ -11425,6 +11425,10 @@ namespace ts {
11425
11425
return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
11426
11426
}
11427
11427
11428
+ function getGlobalAwaitedSymbol(reportErrors: boolean) {
11429
+ return deferredGlobalAwaitedSymbol || (deferredGlobalAwaitedSymbol = getGlobalTypeSymbol("Awaited" as __String, reportErrors));
11430
+ }
11431
+
11428
11432
function getGlobalPromiseType(reportErrors: boolean) {
11429
11433
return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
11430
11434
}
@@ -26163,8 +26167,6 @@ namespace ts {
26163
26167
// creates a `Promise<T>` type where `T` is the promisedType argument
26164
26168
const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
26165
26169
if (globalPromiseType !== emptyGenericType) {
26166
- // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
26167
- promisedType = getAwaitedType(promisedType) || unknownType;
26168
26170
return createTypeReference(globalPromiseType, [promisedType]);
26169
26171
}
26170
26172
@@ -26175,8 +26177,6 @@ namespace ts {
26175
26177
// creates a `PromiseLike<T>` type where `T` is the promisedType argument
26176
26178
const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
26177
26179
if (globalPromiseLikeType !== emptyGenericType) {
26178
- // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
26179
- promisedType = getAwaitedType(promisedType) || unknownType;
26180
26180
return createTypeReference(globalPromiseLikeType, [promisedType]);
26181
26181
}
26182
26182
@@ -29636,98 +29636,26 @@ namespace ts {
29636
29636
return typeAsAwaitable.awaitedTypeOfType = type;
29637
29637
}
29638
29638
29639
- if (type.flags & TypeFlags.Union) {
29640
- let types: Type[] | undefined;
29641
- for (const constituentType of (<UnionType>type).types) {
29642
- types = append<Type>(types, getAwaitedType(constituentType, errorNode, diagnosticMessage, arg0));
29643
- }
29644
-
29645
- if (!types) {
29646
- return undefined;
29647
- }
29648
-
29649
- return typeAsAwaitable.awaitedTypeOfType = getUnionType(types);
29639
+ const symbol = getGlobalAwaitedSymbol(/*reportErrors*/ false);
29640
+ if (!symbol) {
29641
+ return typeAsAwaitable.awaitedTypeOfType = type;
29650
29642
}
29651
29643
29652
- const promisedType = getPromisedTypeOfPromise(type);
29653
- if (promisedType) {
29654
- if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
29655
- // Verify that we don't have a bad actor in the form of a promise whose
29656
- // promised type is the same as the promise type, or a mutually recursive
29657
- // promise. If so, we return undefined as we cannot guess the shape. If this
29658
- // were the actual case in the JavaScript, this Promise would never resolve.
29659
- //
29660
- // An example of a bad actor with a singly-recursive promise type might
29661
- // be:
29662
- //
29663
- // interface BadPromise {
29664
- // then(
29665
- // onfulfilled: (value: BadPromise) => any,
29666
- // onrejected: (error: any) => any): BadPromise;
29667
- // }
29668
- // The above interface will pass the PromiseLike check, and return a
29669
- // promised type of `BadPromise`. Since this is a self reference, we
29670
- // don't want to keep recursing ad infinitum.
29671
- //
29672
- // An example of a bad actor in the form of a mutually-recursive
29673
- // promise type might be:
29674
- //
29675
- // interface BadPromiseA {
29676
- // then(
29677
- // onfulfilled: (value: BadPromiseB) => any,
29678
- // onrejected: (error: any) => any): BadPromiseB;
29679
- // }
29680
- //
29681
- // interface BadPromiseB {
29682
- // then(
29683
- // onfulfilled: (value: BadPromiseA) => any,
29684
- // onrejected: (error: any) => any): BadPromiseA;
29685
- // }
29686
- //
29687
- if (errorNode) {
29688
- error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
29689
- }
29690
- return undefined;
29691
- }
29692
-
29693
- // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
29694
- // See the comments above for more information.
29695
- awaitedTypeStack.push(type.id);
29696
- const awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
29697
- awaitedTypeStack.pop();
29698
-
29699
- if (!awaitedType) {
29700
- return undefined;
29701
- }
29644
+ if (type.aliasSymbol === symbol) {
29645
+ return typeAsAwaitable.awaitedTypeOfType = type;
29646
+ }
29702
29647
29703
- return typeAsAwaitable.awaitedTypeOfType = awaitedType;
29648
+ const result = getTypeAliasInstantiation(symbol, [type]);
29649
+ if (result !== unknownType || type === unknownType || getPromisedTypeOfPromise(type) === unknownType) {
29650
+ return typeAsAwaitable.awaitedTypeOfType = result;
29704
29651
}
29705
29652
29706
- // The type was not a promise, so it could not be unwrapped any further.
29707
- // As long as the type does not have a callable "then" property, it is
29708
- // safe to return the type; otherwise, an error will be reported in
29709
- // the call to getNonThenableType and we will return undefined.
29710
- //
29711
- // An example of a non-promise "thenable" might be:
29712
- //
29713
- // await { then(): void {} }
29714
- //
29715
- // The "thenable" does not match the minimal definition for a promise. When
29716
- // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
29717
- // will never settle. We treat this as an error to help flag an early indicator
29718
- // of a runtime problem. If the user wants to return this value from an async
29719
- // function, they would need to wrap it in some other value. If they want it to
29720
- // be treated as a promise, they can cast to <any>.
29721
- const thenFunction = getTypeOfPropertyOfType(type, "then" as __String);
29722
- if (thenFunction && getSignaturesOfType(thenFunction, SignatureKind.Call).length > 0) {
29723
- if (errorNode) {
29724
- if (!diagnosticMessage) return Debug.fail();
29725
- error(errorNode, diagnosticMessage, arg0);
29726
- }
29727
- return undefined;
29653
+ if (errorNode) {
29654
+ if (!diagnosticMessage) return Debug.fail();
29655
+ error(errorNode, diagnosticMessage, arg0);
29728
29656
}
29729
29657
29730
- return typeAsAwaitable.awaitedTypeOfType = type ;
29658
+ return undefined ;
29731
29659
}
29732
29660
29733
29661
/**
0 commit comments