@@ -148,6 +148,7 @@ namespace ts {
148148 let getGlobalESSymbolConstructorSymbol: () => Symbol;
149149
150150 let getGlobalPromiseConstructorSymbol: () => Symbol;
151+ let tryGetGlobalPromiseConstructorSymbol: () => Symbol;
151152
152153 let globalObjectType: ObjectType;
153154 let globalFunctionType: ObjectType;
@@ -13922,7 +13923,7 @@ namespace ts {
1392213923 * @param returnType The return type of a FunctionLikeDeclaration
1392313924 * @param location The node on which to report the error.
1392413925 */
13925- function checkCorrectPromiseType(returnType: Type, location: Node) {
13926+ function checkCorrectPromiseType(returnType: Type, location: Node, diagnostic: DiagnosticMessage, typeName?: string ) {
1392613927 if (returnType === unknownType) {
1392713928 // The return type already had some other error, so we ignore and return
1392813929 // the unknown type.
@@ -13941,7 +13942,7 @@ namespace ts {
1394113942
1394213943 // The promise type was not a valid type reference to the global promise type, so we
1394313944 // report an error and return the unknown type.
13944- error(location, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type );
13945+ error(location, diagnostic, typeName );
1394513946 return unknownType;
1394613947 }
1394713948
@@ -13961,7 +13962,7 @@ namespace ts {
1396113962 function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
1396213963 if (languageVersion >= ScriptTarget.ES6) {
1396313964 const returnType = getTypeFromTypeNode(node.type);
13964- return checkCorrectPromiseType(returnType, node.type);
13965+ return checkCorrectPromiseType(returnType, node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type );
1396513966 }
1396613967
1396713968 const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
@@ -14007,19 +14008,19 @@ namespace ts {
1400714008
1400814009 const promiseConstructor = getNodeLinks(node.type).resolvedSymbol;
1400914010 if (!promiseConstructor || !symbolIsValue(promiseConstructor)) {
14011+ // try to fall back to global promise type.
1401014012 const typeName = promiseConstructor
1401114013 ? symbolToString(promiseConstructor)
1401214014 : typeToString(promiseType);
14013- error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName);
14014- return unknownType;
14015+ return checkCorrectPromiseType(promiseType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName);
1401514016 }
1401614017
1401714018 // If the Promise constructor, resolved locally, is an alias symbol we should mark it as referenced.
1401814019 checkReturnTypeAnnotationAsExpression(node);
1401914020
1402014021 // Validate the promise constructor type.
1402114022 const promiseConstructorType = getTypeOfSymbol(promiseConstructor);
14022- if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
14023+ if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type , Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
1402314024 return unknownType;
1402414025 }
1402514026
@@ -17520,6 +17521,11 @@ namespace ts {
1752017521 function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
1752117522 // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
1752217523 const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
17524+ const globalPromiseSymbol = tryGetGlobalPromiseConstructorSymbol();
17525+ if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
17526+ return TypeReferenceSerializationKind.Promise;
17527+ }
17528+
1752317529 const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined;
1752417530 if (constructorType && isConstructorType(constructorType)) {
1752517531 return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
@@ -17538,8 +17544,8 @@ namespace ts {
1753817544 else if (type.flags & TypeFlags.Any) {
1753917545 return TypeReferenceSerializationKind.ObjectType;
1754017546 }
17541- else if (isTypeOfKind(type, TypeFlags.Void)) {
17542- return TypeReferenceSerializationKind.VoidType ;
17547+ else if (isTypeOfKind(type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never )) {
17548+ return TypeReferenceSerializationKind.VoidNullableOrNeverType ;
1754317549 }
1754417550 else if (isTypeOfKind(type, TypeFlags.Boolean)) {
1754517551 return TypeReferenceSerializationKind.BooleanType;
@@ -17837,6 +17843,7 @@ namespace ts {
1783717843 getGlobalPromiseLikeType = memoize(() => getGlobalType("PromiseLike", /*arity*/ 1));
1783817844 getInstantiatedGlobalPromiseLikeType = memoize(createInstantiatedPromiseLikeType);
1783917845 getGlobalPromiseConstructorSymbol = memoize(() => getGlobalValueSymbol("Promise"));
17846+ tryGetGlobalPromiseConstructorSymbol = memoize(() => getGlobalSymbol("Promise", SymbolFlags.Value, /*diagnostic*/ undefined) && getGlobalPromiseConstructorSymbol());
1784017847 getGlobalPromiseConstructorLikeType = memoize(() => getGlobalType("PromiseConstructorLike"));
1784117848 getGlobalThenableType = memoize(createThenableType);
1784217849
0 commit comments