@@ -13469,7 +13469,6 @@ namespace ts {
1346913469        }
1347013470
1347113471        function getGlobalAwaitedSymbol(reportErrors: boolean): Symbol | undefined {
13472-             if (reportErrors) debugger;
1347313472            // Only cache `unknownSymbol` if we are reporting errors so that we don't report the error more than once.
1347413473            deferredGlobalAwaitedSymbol ||= getGlobalTypeAliasSymbol("Awaited" as __String, /*arity*/ 1, reportErrors) || (reportErrors ? unknownSymbol : undefined);
1347513474            return deferredGlobalAwaitedSymbol === unknownSymbol ? undefined : deferredGlobalAwaitedSymbol;
@@ -32560,10 +32559,8 @@ namespace ts {
3256032559                let wouldWorkWithAwait = false;
3256132560                const errNode = errorNode || operatorToken;
3256232561                if (isRelated) {
32563-                     let awaitedLeftType = getAwaitedType(leftType);
32564-                     let awaitedRightType = getAwaitedType(rightType);
32565-                     awaitedLeftType &&= unwrapAwaitedType(awaitedLeftType);
32566-                     awaitedRightType &&= unwrapAwaitedType(awaitedRightType);
32562+                     const awaitedLeftType = unwrapAwaitedType(getAwaitedType(leftType));
32563+                     const awaitedRightType = unwrapAwaitedType(getAwaitedType(rightType));
3256732564                    wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType)
3256832565                        && !!(awaitedLeftType && awaitedRightType)
3256932566                        && isRelated(awaitedLeftType, awaitedRightType);
@@ -34643,9 +34640,14 @@ namespace ts {
3464334640        }
3464434641
3464534642        /**
34646-          * Determines whether a type has  a callable `then` member.
34643+          * Determines whether a type is an object with  a callable `then` member.
3464734644         */
3464834645        function isThenableType(type: Type): boolean {
34646+             if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) {
34647+                 // primitive types cannot be considered "thenable" since they are not objects.
34648+                 return false;
34649+             }
34650+ 
3464934651            const thenFunction = getTypeOfPropertyOfType(type, "then" as __String);
3465034652            return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull), SignatureKind.Call).length > 0;
3465134653        }
@@ -34667,13 +34669,24 @@ namespace ts {
3466734669        /**
3466834670         * For a generic `Awaited<T>`, gets `T`.
3466934671         */
34670-         function unwrapAwaitedType(type: Type) {
34672+         function unwrapAwaitedType(type: Type): Type;
34673+         function unwrapAwaitedType(type: Type | undefined): Type | undefined;
34674+         function unwrapAwaitedType(type: Type | undefined) {
34675+             if (!type) return undefined;
3467134676            return type.flags & TypeFlags.Union ? mapType(type, unwrapAwaitedType) :
3467234677                isAwaitedTypeInstantiation(type) ? type.aliasTypeArguments[0] :
3467334678                type;
3467434679        }
3467534680
3467634681        function createAwaitedTypeIfNeeded(type: Type): Type {
34682+             // We wrap type `T` in `Awaited<T>` based on the following conditions:
34683+             // - `T` is not already an `Awaited<U>`, and
34684+             // - `T` is generic, and
34685+             // - One of the following applies:
34686+             //   - `T` has no base constraint, or
34687+             //   - The base constraint of `T` is `any`, `unknown`, `object`, or `{}`, or
34688+             //   - The base constraint of `T` is an object type with a callable `then` method.
34689+ 
3467734690            if (isTypeAny(type)) {
3467834691                return type;
3467934692            }
@@ -34684,13 +34697,18 @@ namespace ts {
3468434697            }
3468534698
3468634699            // Only instantiate `Awaited<T>` if `T` contains possibly non-primitive types.
34687-             if (isGenericObjectType(type) && !allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) {
34688-                 // Nothing to do if `Awaited<T>` doesn't exist
34689-                 const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ true);
34690-                 if (awaitedSymbol) {
34691-                     // Unwrap unions that may contain `Awaited<T>`, otherwise its possible to manufacture an `Awaited<Awaited<T> | U>` where
34692-                     // an `Awaited<T | U>` would suffice.
34693-                     return getTypeAliasInstantiation(awaitedSymbol, [unwrapAwaitedType(type)]);
34700+             if (isGenericObjectType(type)) {
34701+                 const baseConstraint = getBaseConstraintOfType(type);
34702+                 // Only instantiate `Awaited<T>` if `T` has no base constraint, or the base constraint of `T` is `any`, `unknown`, `{}`, `object`,
34703+                 // or is promise-like.
34704+                 if (!baseConstraint || (baseConstraint.flags & TypeFlags.AnyOrUnknown) || isEmptyObjectType(baseConstraint) || isThenableType(baseConstraint)) {
34705+                     // Nothing to do if `Awaited<T>` doesn't exist
34706+                     const awaitedSymbol = getGlobalAwaitedSymbol(/*reportErrors*/ true);
34707+                     if (awaitedSymbol) {
34708+                         // Unwrap unions that may contain `Awaited<T>`, otherwise its possible to manufacture an `Awaited<Awaited<T> | U>` where
34709+                         // an `Awaited<T | U>` would suffice.
34710+                         return getTypeAliasInstantiation(awaitedSymbol, [unwrapAwaitedType(type)]);
34711+                     }
3469434712                }
3469534713            }
3469634714
@@ -34731,12 +34749,6 @@ namespace ts {
3473134749                return typeAsAwaitable.awaitedTypeOfType && createAwaitedTypeIfNeeded(typeAsAwaitable.awaitedTypeOfType);
3473234750            }
3473334751
34734-             // primitives with a `{ then() }` won't be unwrapped/adopted. This prevents `Awaited<T>` when `T extends string`
34735-             // (or another primitive), since the `Awaited<T>` type only unwraps `object` types.
34736-             if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) {
34737-                 return type;
34738-             }
34739- 
3474034752            const promisedType = getPromisedTypeOfPromise(type);
3474134753            if (promisedType) {
3474234754                if (type.id === promisedType.id || awaitedTypeStack.lastIndexOf(promisedType.id) >= 0) {
@@ -34865,7 +34877,7 @@ namespace ts {
3486534877                if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
3486634878                    // The promise type was not a valid type reference to the global promise type, so we
3486734879                    // report an error and return the unknown type.
34868-                     error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(unwrapAwaitedType(getAwaitedType(returnType) || voidType) ));
34880+                     error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(unwrapAwaitedType(getAwaitedType(returnType))  || voidType));
3486934881                    return;
3487034882                }
3487134883            }
@@ -36865,7 +36877,7 @@ namespace ts {
3686536877            // - `Generator<T, TReturn, TNext>` or `AsyncGenerator<T, TReturn, TNext>`
3686636878            if (isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) {
3686736879                const [yieldType, returnType, nextType] = getTypeArguments(type as GenericType);
36868-                 return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType));
36880+                 return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(resolver.resolveIterationType( yieldType, /*errorNode*/ undefined) || yieldType, resolver.resolveIterationType(returnType, /*errorNode*/ undefined) ||  returnType, nextType));
3686936881            }
3687036882        }
3687136883
@@ -37197,8 +37209,8 @@ namespace ts {
3719737209        function unwrapReturnType(returnType: Type, functionFlags: FunctionFlags) {
3719837210            const isGenerator = !!(functionFlags & FunctionFlags.Generator);
3719937211            const isAsync = !!(functionFlags & FunctionFlags.Async);
37200-             return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) ??  errorType :
37201-                 isAsync ? unwrapAwaitedType(getAwaitedType(returnType) ??  errorType)  :
37212+             return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) ||  errorType :
37213+                 isAsync ? unwrapAwaitedType(getAwaitedType(returnType)) ||  errorType :
3720237214                returnType;
3720337215        }
3720437216
0 commit comments