@@ -2629,7 +2629,7 @@ namespace ts {
26292629 }
26302630 }
26312631 else if (declaration.kind === SyntaxKind.Parameter) {
2632- // If it's a parameter, see if the parent has a jsdoc comment with an @param
2632+ // If it's a parameter, see if the parent has a jsdoc comment with an @param
26332633 // annotation.
26342634 const paramTag = getCorrespondingJSDocParameterTag(<ParameterDeclaration>declaration);
26352635 if (paramTag && paramTag.typeExpression) {
@@ -2644,7 +2644,7 @@ namespace ts {
26442644 function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type {
26452645 if (declaration.parserContextFlags & ParserContextFlags.JavaScriptFile) {
26462646 // If this is a variable in a JavaScript file, then use the JSDoc type (if it has
2647- // one as its type), otherwise fallback to the below standard TS codepaths to
2647+ // one as its type), otherwise fallback to the below standard TS codepaths to
26482648 // try to figure it out.
26492649 const type = getTypeForVariableLikeDeclarationFromJSDocComment(declaration);
26502650 if (type && type !== unknownType) {
@@ -4069,7 +4069,7 @@ namespace ts {
40694069 const isJSConstructSignature = isJSDocConstructSignature(declaration);
40704070 let returnType: Type = undefined;
40714071
4072- // If this is a JSDoc construct signature, then skip the first parameter in the
4072+ // If this is a JSDoc construct signature, then skip the first parameter in the
40734073 // parameter list. The first parameter represents the return type of the construct
40744074 // signature.
40754075 for (let i = isJSConstructSignature ? 1 : 0, n = declaration.parameters.length; i < n; i++) {
@@ -4472,7 +4472,7 @@ namespace ts {
44724472 }
44734473
44744474 if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
4475- // A JSDocTypeReference may have resolved to a value (as opposed to a type). In
4475+ // A JSDocTypeReference may have resolved to a value (as opposed to a type). In
44764476 // that case, the type of this reference is just the type of the value we resolved
44774477 // to.
44784478 return getTypeOfSymbol(symbol);
@@ -10479,7 +10479,7 @@ namespace ts {
1047910479
1048010480 /*
1048110481 *TypeScript Specification 1.0 (6.3) - July 2014
10482- * An explicitly typed function whose return type isn't the Void type,
10482+ * An explicitly typed function whose return type isn't the Void type,
1048310483 * the Any type, or a union type containing the Void or Any type as a constituent
1048410484 * must have at least one return statement somewhere in its body.
1048510485 * An exception to this rule is if the function implementation consists of a single 'throw' statement.
@@ -12508,6 +12508,33 @@ namespace ts {
1250812508 }
1250912509 }
1251012510
12511+ /**
12512+ * Checks that the return type provided is an instantiation of the global Promise<T> type
12513+ * and returns the awaited type of the return type.
12514+ */
12515+ function checkCorrectPromiseType(returnType: Type, location: Node) {
12516+ if (returnType === unknownType) {
12517+ // The return type already had some other error, so we ignore and return
12518+ // the unknown type.
12519+ return unknownType;
12520+ }
12521+
12522+ const globalPromiseType = getGlobalPromiseType();
12523+ if (globalPromiseType === emptyGenericType
12524+ || globalPromiseType === getTargetType(returnType)) {
12525+ // Either we couldn't resolve the global promise type, which would have already
12526+ // reported an error, or we could resolve it and the return type is a valid type
12527+ // reference to the global type. In either case, we return the awaited type for
12528+ // the return type.
12529+ return checkAwaitedType(returnType, location, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
12530+ }
12531+
12532+ // The promise type was not a valid type reference to the global promise type, so we
12533+ // report an error and return the unknown type.
12534+ error(location, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T);
12535+ return unknownType;
12536+ }
12537+
1251112538 /**
1251212539 * Checks the return type of an async function to ensure it is a compatible
1251312540 * Promise implementation.
@@ -12522,6 +12549,11 @@ namespace ts {
1252212549 * callable `then` signature.
1252312550 */
1252412551 function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
12552+ if (languageVersion >= ScriptTarget.ES6) {
12553+ const returnType = getTypeFromTypeNode(node.type);
12554+ return checkCorrectPromiseType(returnType, node.type);
12555+ }
12556+
1252512557 const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
1252612558 if (globalPromiseConstructorLikeType === emptyObjectType) {
1252712559 // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
@@ -12563,21 +12595,6 @@ namespace ts {
1256312595 return unknownType;
1256412596 }
1256512597
12566- if (languageVersion >= ScriptTarget.ES6) {
12567- const promisedType = getPromisedType(promiseType);
12568- if (!promisedType) {
12569- error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeToString(promiseType));
12570- return unknownType;
12571- }
12572-
12573- const promiseInstantiation = createPromiseType(promisedType);
12574- if (!checkTypeAssignableTo(promiseInstantiation, promiseType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
12575- return unknownType;
12576- }
12577-
12578- return promisedType;
12579- }
12580-
1258112598 const promiseConstructor = getNodeLinks(node.type).resolvedSymbol;
1258212599 if (!promiseConstructor || !symbolIsValue(promiseConstructor)) {
1258312600 const typeName = promiseConstructor
0 commit comments