diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eaa6a2937cb6e..fae32cff4c981 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7545,9 +7545,10 @@ namespace ts { getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent).symbol)) : undefined; const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration); - const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType); const hasRestLikeParameter = hasRestParameter(declaration) || isInJavaScriptFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters); - links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, /*resolvedTypePredicate*/ undefined, minArgumentCount, hasRestLikeParameter, hasLiteralTypes); + links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, + /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, + minArgumentCount, hasRestLikeParameter, hasLiteralTypes); } return links.resolvedSignature; } @@ -7577,38 +7578,15 @@ namespace ts { return true; } - function getSignatureReturnTypeFromDeclaration(declaration: SignatureDeclaration | JSDocSignature, isJSConstructSignature: boolean, classType: Type | undefined) { - if (isJSConstructSignature) { - return getTypeFromTypeNode((declaration.parameters[0] as ParameterDeclaration).type!); // TODO: GH#18217 - } - else if (classType) { - return classType; - } - - const typeNode = getEffectiveReturnTypeNode(declaration); - if (typeNode) { - return getTypeFromTypeNode(typeNode); - } - - // TypeScript 1.0 spec (April 2014): - // If only one accessor includes a type annotation, the other behaves as if it had the same type annotation. - if (declaration.kind === SyntaxKind.GetAccessor && !hasNonBindableDynamicName(declaration)) { - const setter = getDeclarationOfKind(getSymbolOfNode(declaration), SyntaxKind.SetAccessor); - return getAnnotatedAccessorType(setter); - } - const typeFromTag = getReturnTypeOfTypeTag(declaration); - if (typeFromTag) { - return typeFromTag; - } - if (nodeIsMissing((declaration).body)) { - return anyType; - } + function getSignatureOfTypeTag(node: SignatureDeclaration | JSDocSignature) { + const typeTag = isInJavaScriptFile(node) ? getJSDocTypeTag(node) : undefined; + const signature = typeTag && typeTag.typeExpression && getSingleCallSignature(getTypeFromTypeNode(typeTag.typeExpression)); + return signature && getErasedSignature(signature); } function getReturnTypeOfTypeTag(node: SignatureDeclaration | JSDocSignature) { - const typeTag = isInJavaScriptFile(node) ? getJSDocTypeTag(node) : undefined; - const signatures = typeTag && typeTag.typeExpression && getSignaturesOfType(getTypeFromTypeNode(typeTag.typeExpression), SignatureKind.Call); - return signatures && signatures.length === 1 ? getReturnTypeOfSignature(signatures[0]) : undefined; + const signature = getSignatureOfTypeTag(node); + return signature && getReturnTypeOfSignature(signature); } function containsArgumentsReference(declaration: SignatureDeclaration): boolean { @@ -7709,34 +7687,59 @@ namespace ts { if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) { return errorType; } - let type: Type; - if (signature.target) { - type = instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!); - } - else if (signature.unionSignatures) { - type = getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype); - } - else { - type = getReturnTypeFromBody(signature.declaration); - } + let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!) : + signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) : + getReturnTypeFromAnnotation(signature.declaration!) || + (nodeIsMissing((signature.declaration).body) ? anyType : getReturnTypeFromBody(signature.declaration)); if (!popTypeResolution()) { - type = anyType; - if (noImplicitAny) { - const declaration = signature.declaration; - const name = getNameOfDeclaration(declaration); - if (name) { - error(name, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, declarationNameToString(name)); + if (signature.declaration) { + const typeNode = getEffectiveReturnTypeNode(signature.declaration); + if (typeNode) { + error(typeNode, Diagnostics.Return_type_annotation_circularly_references_itself); } - else { - error(declaration, Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions); + else if (noImplicitAny) { + const declaration = signature.declaration; + const name = getNameOfDeclaration(declaration); + if (name) { + error(name, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, declarationNameToString(name)); + } + else { + error(declaration, Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions); + } } } + type = anyType; } signature.resolvedReturnType = type; } return signature.resolvedReturnType; } + function getReturnTypeFromAnnotation(declaration: SignatureDeclaration | JSDocSignature) { + if (declaration.kind === SyntaxKind.Constructor) { + return getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent).symbol)); + } + if (isJSDocConstructSignature(declaration)) { + return getTypeFromTypeNode((declaration.parameters[0] as ParameterDeclaration).type!); // TODO: GH#18217 + } + const typeNode = getEffectiveReturnTypeNode(declaration); + if (typeNode) { + return getTypeFromTypeNode(typeNode); + } + if (declaration.kind === SyntaxKind.GetAccessor && !hasNonBindableDynamicName(declaration)) { + const jsDocType = isInJavaScriptFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration); + if (jsDocType) { + return jsDocType; + } + const setter = getDeclarationOfKind(getSymbolOfNode(declaration), SyntaxKind.SetAccessor); + const setterType = getAnnotatedAccessorType(setter); + if (setterType) { + return setterType; + } + } + return getReturnTypeOfTypeTag(declaration); + } + function isResolvingReturnTypeOfSignature(signature: Signature) { return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0; } @@ -15928,19 +15931,16 @@ namespace ts { function getContextualReturnType(functionDecl: SignatureDeclaration): Type | undefined { // If the containing function has a return type annotation, is a constructor, or is a get accessor whose // corresponding set accessor has a type annotation, return statements in the function are contextually typed - if (functionDecl.kind === SyntaxKind.Constructor || - getEffectiveReturnTypeNode(functionDecl) || - isGetAccessorWithAnnotatedSetAccessor(functionDecl)) { - return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); + const returnType = getReturnTypeFromAnnotation(functionDecl); + if (returnType) { + return returnType; } - // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature // and that call signature is non-generic, return statements are contextually typed by the return type of the signature const signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } - return undefined; } @@ -16455,16 +16455,11 @@ namespace ts { // union type of return types from these signatures function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature | undefined { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); - let type: Type | undefined; - if (isInJavaScriptFile(node)) { - const jsdoc = getJSDocType(node); - if (jsdoc) { - type = getTypeFromTypeNode(jsdoc); - } - } - if (!type) { - type = getContextualTypeForFunctionLikeDeclaration(node); + const typeTagSignature = getSignatureOfTypeTag(node); + if (typeTagSignature) { + return typeTagSignature; } + const type = getContextualTypeForFunctionLikeDeclaration(node); if (!type) { return undefined; } @@ -20761,7 +20756,7 @@ namespace ts { contextualSignature : instantiateSignature(contextualSignature, contextualMapper); assignContextualParameterTypes(signature, instantiatedContextualSignature); } - if (!getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) { + if (!getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) { const returnType = getReturnTypeFromBody(node, checkMode); if (!signature.resolvedReturnType) { signature.resolvedReturnType = returnType; @@ -20777,12 +20772,9 @@ namespace ts { } function getReturnOrPromisedType(node: FunctionLikeDeclaration | MethodSignature, functionFlags: FunctionFlags) { - const returnTypeNode = getEffectiveReturnTypeNode(node); - return returnTypeNode && - ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ? - checkAsyncFunctionReturnType(node, returnTypeNode) : // Async function - getTypeFromTypeNode(returnTypeNode)) || // AsyncGenerator function, Generator function, or normal function - getReturnTypeOfTypeTag(node); // type from JSDoc @type tag + const type = getReturnTypeFromAnnotation(node); + return type && ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) ? + getAwaitedType(type) || errorType : type; } function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) { @@ -21649,9 +21641,9 @@ namespace ts { // There is no point in doing an assignability check if the function // has no explicit return type because the return type is directly computed // from the yield expressions. - const returnType = getEffectiveReturnTypeNode(func); + const returnType = getReturnTypeFromAnnotation(func); if (returnType) { - const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), isAsync) || anyType; + const signatureElementType = getIteratedTypeOfGenerator(returnType, isAsync) || anyType; checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureElementType, node.expression || node, node.expression); } @@ -22748,6 +22740,10 @@ namespace ts { checkTypeAssignableTo(constraintType, keyofConstraintType, node.typeParameter.constraint); } + function checkThisType(node: ThisTypeNode) { + getTypeFromThisTypeNode(node); + } + function checkTypeOperator(node: TypeOperatorNode) { checkGrammarTypeOperatorNode(node); checkSourceElement(node.type); @@ -23301,16 +23297,15 @@ namespace ts { * Checks the return type of an async function to ensure it is a compatible * Promise implementation. * - * This checks that an async function has a valid Promise-compatible return type, - * and returns the *awaited type* of the promise. An async function has a valid - * Promise-compatible return type if the resolved value of the return type has a - * construct signature that takes in an `initializer` function that in turn supplies - * a `resolve` function as one of its arguments and results in an object with a - * callable `then` signature. + * This checks that an async function has a valid Promise-compatible return type. + * An async function has a valid Promise-compatible return type if the resolved value + * of the return type has a construct signature that takes in an `initializer` function + * that in turn supplies a `resolve` function as one of its arguments and results in an + * object with a callable `then` signature. * * @param node The signature to check */ - function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration | MethodSignature, returnTypeNode: TypeNode): Type { + function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration | MethodSignature, returnTypeNode: TypeNode) { // As part of our emit for an async function, we will need to emit the entity name of // the return type annotation as an expression. To meet the necessary runtime semantics // for __awaiter, we must also check that the type of the declaration (e.g. the static @@ -23339,14 +23334,14 @@ namespace ts { if (languageVersion >= ScriptTarget.ES2015) { if (returnType === errorType) { - return errorType; + return; } const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); - return errorType; + return; } } else { @@ -23354,13 +23349,13 @@ namespace ts { markTypeNodeAsReferenced(returnTypeNode); if (returnType === errorType) { - return errorType; + return; } const promiseConstructorName = getEntityNameFromTypeNode(returnTypeNode); if (promiseConstructorName === undefined) { error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); - return errorType; + return; } const promiseConstructorSymbol = resolveEntityName(promiseConstructorName, SymbolFlags.Value, /*ignoreErrors*/ true); @@ -23372,7 +23367,7 @@ namespace ts { else { error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); } - return errorType; + return; } const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true); @@ -23380,12 +23375,12 @@ namespace ts { // If we couldn't resolve the global PromiseConstructorLike type we cannot verify // compatibility with __awaiter. error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); - return errorType; + return; } if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) { - return errorType; + return; } // Verify there is no local declaration that could collide with the promise constructor. @@ -23395,12 +23390,10 @@ namespace ts { error(collidingSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, idText(rootName), entityNameToString(promiseConstructorName)); - return errorType; + return; } } - - // Get and return the awaited type of the return type. - return checkAwaitedType(returnType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); + checkAwaitedType(returnType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } /** Check a decorator */ @@ -25018,11 +25011,6 @@ namespace ts { // TODO: Check that target label is valid } - function isGetAccessorWithAnnotatedSetAccessor(node: SignatureDeclaration) { - return node.kind === SyntaxKind.GetAccessor - && getEffectiveSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)!) !== undefined; - } - function isUnwrappedReturnTypeVoidOrAny(func: SignatureDeclaration, returnType: Type): boolean { const unwrappedReturnType = (getFunctionFlags(func) & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ? getPromisedTypeOfPromise(returnType) // Async function @@ -25065,7 +25053,7 @@ namespace ts { error(node, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } - else if (getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func) || getReturnTypeOfTypeTag(func)) { + else if (getReturnTypeFromAnnotation(func)) { if (functionFlags & FunctionFlags.Async) { // Async function const promisedType = getPromisedTypeOfPromise(returnType); const awaitedType = checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); @@ -26624,6 +26612,8 @@ namespace ts { case SyntaxKind.OptionalType: case SyntaxKind.RestType: return checkSourceElement((node).type); + case SyntaxKind.ThisType: + return checkThisType(node); case SyntaxKind.TypeOperator: return checkTypeOperator(node); case SyntaxKind.ConditionalType: diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 487fb3344287a..ae6ec40fd9369 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2068,6 +2068,10 @@ "category": "Error", "code": 2576 }, + "Return type annotation circularly references itself.": { + "category": "Error", + "code": 2577 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 56ea3cace0c39..b285a9878486e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3374,10 +3374,9 @@ namespace ts { * JavaScript file, gets the return type annotation from JSDoc. */ export function getEffectiveReturnTypeNode(node: SignatureDeclaration | JSDocSignature): TypeNode | undefined { - if (isJSDocSignature(node)) { - return node.type && node.type.typeExpression && node.type.typeExpression.type; - } - return node.type || (isInJavaScriptFile(node) ? getJSDocReturnType(node) : undefined); + return isJSDocSignature(node) ? + node.type && node.type.typeExpression && node.type.typeExpression.type : + node.type || (isInJavaScriptFile(node) ? getJSDocReturnType(node) : undefined); } export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray { diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt index 027551ae4b822..6b4b0a71c6fe1 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(6,23): error TS1055: Type '{}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. +tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(6,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(7,23): error TS1055: Type 'any' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(8,23): error TS1055: Type 'number' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. +tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(8,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,23): error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. -tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. Type 'Thenable' is not assignable to type 'PromiseLike'. Types of property 'then' are incompatible. @@ -12,7 +13,7 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member. -==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts (8 errors) ==== +==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts (9 errors) ==== declare class Thenable { then(): void; } declare let a: any; declare let obj: { then: string; }; @@ -21,19 +22,21 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 async function fn2(): { } { } // error ~~~ !!! error TS1055: Type '{}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. + ~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. async function fn3(): any { } // error ~~~ !!! error TS1055: Type 'any' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. async function fn4(): number { } // error ~~~~~~ !!! error TS1055: Type 'number' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. + ~~~~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. async function fn5(): PromiseLike { } // error ~~~~~~~~~~~~~~~~~ !!! error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. async function fn6(): Thenable { } // error ~~~~~~~~ -!!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. - ~~~~~~~~ !!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. !!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike'. !!! error TS1055: Types of property 'then' are incompatible. diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt index d7f27281d6d40..5ff67861350fd 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt @@ -1,13 +1,15 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(6,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(6,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(7,23): error TS1064: The return type of an async function or method must be the global Promise type. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(8,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(8,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(9,23): error TS1064: The return type of an async function or method must be the global Promise type. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(10,23): error TS1064: The return type of an async function or method must be the global Promise type. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member. -==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts (7 errors) ==== +==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts (9 errors) ==== declare class Thenable { then(): void; } declare let a: any; declare let obj: { then: string; }; @@ -16,12 +18,16 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1 async function fn2(): { } { } // error ~~~ !!! error TS1064: The return type of an async function or method must be the global Promise type. + ~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. async function fn3(): any { } // error ~~~ !!! error TS1064: The return type of an async function or method must be the global Promise type. async function fn4(): number { } // error ~~~~~~ !!! error TS1064: The return type of an async function or method must be the global Promise type. + ~~~~~~ +!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. async function fn5(): PromiseLike { } // error ~~~~~~~~~~~~~~~~~ !!! error TS1064: The return type of an async function or method must be the global Promise type. diff --git a/tests/baselines/reference/checkJsdocTypeTag6.types b/tests/baselines/reference/checkJsdocTypeTag6.types index a2d9ffbbd7af6..16f22e1332b9f 100644 --- a/tests/baselines/reference/checkJsdocTypeTag6.types +++ b/tests/baselines/reference/checkJsdocTypeTag6.types @@ -16,11 +16,11 @@ var g = function (prop) { /** @type {(a: number) => number} */ function add1(a, b) { return a + b; } ->add1 : (a: any, b: any) => number ->a : any +>add1 : (a: number, b: any) => number +>a : number >b : any >a + b : any ->a : any +>a : number >b : any /** @type {(a: number, b: number) => number} */ diff --git a/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt b/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt index 26bff709ae14f..1fb989b75f5c1 100644 --- a/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt +++ b/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt @@ -2,10 +2,15 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(2,5): error TS2502: 'varOfAliasedType1' is referenced directly or indirectly in its own type annotation. tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(4,5): error TS2502: 'varOfAliasedType2' is referenced directly or indirectly in its own type annotation. tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(5,6): error TS2456: Type alias 'typeAlias2' circularly references itself. +tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(7,18): error TS2577: Return type annotation circularly references itself. tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(9,6): error TS2456: Type alias 'typeAlias3' circularly references itself. +tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(18,6): error TS2456: Type alias 'R' circularly references itself. +tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(19,29): error TS2577: Return type annotation circularly references itself. +tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(25,6): error TS2456: Type alias 'R2' circularly references itself. +tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,15): error TS2577: Return type annotation circularly references itself. -==== tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts (5 errors) ==== +==== tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts (10 errors) ==== type typeAlias1 = typeof varOfAliasedType1; ~~~~~~~~~~ !!! error TS2456: Type alias 'typeAlias1' circularly references itself. @@ -21,8 +26,35 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO !!! error TS2456: Type alias 'typeAlias2' circularly references itself. function func(): typeAlias3 { return null; } + ~~~~~~~~~~ +!!! error TS2577: Return type annotation circularly references itself. var varOfAliasedType3 = func(); type typeAlias3 = typeof varOfAliasedType3; ~~~~~~~~~~ !!! error TS2456: Type alias 'typeAlias3' circularly references itself. + + // Repro from #26104 + + interface Input { + a: number; + b: number; + } + + type R = ReturnType; + ~ +!!! error TS2456: Type alias 'R' circularly references itself. + function mul(input: Input): R { + ~ +!!! error TS2577: Return type annotation circularly references itself. + return input.a * input.b; + } + + // Repro from #26104 + + type R2 = ReturnType; + ~~ +!!! error TS2456: Type alias 'R2' circularly references itself. + function f(): R2 { return 0; } + ~~ +!!! error TS2577: Return type annotation circularly references itself. \ No newline at end of file diff --git a/tests/baselines/reference/circularTypeofWithVarOrFunc.js b/tests/baselines/reference/circularTypeofWithVarOrFunc.js index 9d569a3d2195d..07a95710372f6 100644 --- a/tests/baselines/reference/circularTypeofWithVarOrFunc.js +++ b/tests/baselines/reference/circularTypeofWithVarOrFunc.js @@ -8,6 +8,23 @@ type typeAlias2 = typeof varOfAliasedType2; function func(): typeAlias3 { return null; } var varOfAliasedType3 = func(); type typeAlias3 = typeof varOfAliasedType3; + +// Repro from #26104 + +interface Input { + a: number; + b: number; +} + +type R = ReturnType; +function mul(input: Input): R { + return input.a * input.b; +} + +// Repro from #26104 + +type R2 = ReturnType; +function f(): R2 { return 0; } //// [circularTypeofWithVarOrFunc.js] @@ -15,3 +32,7 @@ var varOfAliasedType1; var varOfAliasedType2; function func() { return null; } var varOfAliasedType3 = func(); +function mul(input) { + return input.a * input.b; +} +function f() { return 0; } diff --git a/tests/baselines/reference/circularTypeofWithVarOrFunc.symbols b/tests/baselines/reference/circularTypeofWithVarOrFunc.symbols index e32fde1fc7d38..d5cb06383327d 100644 --- a/tests/baselines/reference/circularTypeofWithVarOrFunc.symbols +++ b/tests/baselines/reference/circularTypeofWithVarOrFunc.symbols @@ -27,3 +27,46 @@ type typeAlias3 = typeof varOfAliasedType3; >typeAlias3 : Symbol(typeAlias3, Decl(circularTypeofWithVarOrFunc.ts, 7, 31)) >varOfAliasedType3 : Symbol(varOfAliasedType3, Decl(circularTypeofWithVarOrFunc.ts, 7, 3)) +// Repro from #26104 + +interface Input { +>Input : Symbol(Input, Decl(circularTypeofWithVarOrFunc.ts, 8, 43)) + + a: number; +>a : Symbol(Input.a, Decl(circularTypeofWithVarOrFunc.ts, 12, 17)) + + b: number; +>b : Symbol(Input.b, Decl(circularTypeofWithVarOrFunc.ts, 13, 12)) +} + +type R = ReturnType; +>R : Symbol(R, Decl(circularTypeofWithVarOrFunc.ts, 15, 1)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>mul : Symbol(mul, Decl(circularTypeofWithVarOrFunc.ts, 17, 32)) + +function mul(input: Input): R { +>mul : Symbol(mul, Decl(circularTypeofWithVarOrFunc.ts, 17, 32)) +>input : Symbol(input, Decl(circularTypeofWithVarOrFunc.ts, 18, 13)) +>Input : Symbol(Input, Decl(circularTypeofWithVarOrFunc.ts, 8, 43)) +>R : Symbol(R, Decl(circularTypeofWithVarOrFunc.ts, 15, 1)) + + return input.a * input.b; +>input.a : Symbol(Input.a, Decl(circularTypeofWithVarOrFunc.ts, 12, 17)) +>input : Symbol(input, Decl(circularTypeofWithVarOrFunc.ts, 18, 13)) +>a : Symbol(Input.a, Decl(circularTypeofWithVarOrFunc.ts, 12, 17)) +>input.b : Symbol(Input.b, Decl(circularTypeofWithVarOrFunc.ts, 13, 12)) +>input : Symbol(input, Decl(circularTypeofWithVarOrFunc.ts, 18, 13)) +>b : Symbol(Input.b, Decl(circularTypeofWithVarOrFunc.ts, 13, 12)) +} + +// Repro from #26104 + +type R2 = ReturnType; +>R2 : Symbol(R2, Decl(circularTypeofWithVarOrFunc.ts, 20, 1)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>f : Symbol(f, Decl(circularTypeofWithVarOrFunc.ts, 24, 31)) + +function f(): R2 { return 0; } +>f : Symbol(f, Decl(circularTypeofWithVarOrFunc.ts, 24, 31)) +>R2 : Symbol(R2, Decl(circularTypeofWithVarOrFunc.ts, 20, 1)) + diff --git a/tests/baselines/reference/circularTypeofWithVarOrFunc.types b/tests/baselines/reference/circularTypeofWithVarOrFunc.types index adb300efee1ca..c2c8ba7947fb5 100644 --- a/tests/baselines/reference/circularTypeofWithVarOrFunc.types +++ b/tests/baselines/reference/circularTypeofWithVarOrFunc.types @@ -26,3 +26,41 @@ type typeAlias3 = typeof varOfAliasedType3; >typeAlias3 : any >varOfAliasedType3 : any +// Repro from #26104 + +interface Input { + a: number; +>a : number + + b: number; +>b : number +} + +type R = ReturnType; +>R : any +>mul : (input: Input) => any + +function mul(input: Input): R { +>mul : (input: Input) => any +>input : Input + + return input.a * input.b; +>input.a * input.b : number +>input.a : number +>input : Input +>a : number +>input.b : number +>input : Input +>b : number +} + +// Repro from #26104 + +type R2 = ReturnType; +>R2 : any +>f : () => any + +function f(): R2 { return 0; } +>f : () => any +>0 : 0 + diff --git a/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt b/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt index 2a6bab18cbaac..ad5fe6dc1aedc 100644 --- a/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt +++ b/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt @@ -1,13 +1,16 @@ +tests/cases/compiler/recursiveResolveTypeMembers.ts(4,49): error TS2577: Return type annotation circularly references itself. tests/cases/compiler/recursiveResolveTypeMembers.ts(4,58): error TS2304: Cannot find name 'H'. tests/cases/compiler/recursiveResolveTypeMembers.ts(4,62): error TS2574: A rest element type must be an array type. tests/cases/compiler/recursiveResolveTypeMembers.ts(4,79): error TS2304: Cannot find name 'R'. -==== tests/cases/compiler/recursiveResolveTypeMembers.ts (3 errors) ==== +==== tests/cases/compiler/recursiveResolveTypeMembers.ts (4 errors) ==== // Repro from #25291 type PromisedTuple void> = U extends (h: infer H, ...args: infer R) => [Promise, ...PromisedTuple] ? [] : [] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2577: Return type annotation circularly references itself. ~ !!! error TS2304: Cannot find name 'H'. ~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types index b10e4e5d4d07b..481abe9e59ca8 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types +++ b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types @@ -388,11 +388,11 @@ declare var G: GConstructor; >G : GConstructor var obj13: G1 | G2; ->obj13 : G2 | G1 +>obj13 : G1 | G2 if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. >obj13 instanceof G : boolean ->obj13 : G2 | G1 +>obj13 : G1 | G2 >G : GConstructor obj13.foo1; diff --git a/tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts b/tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts index e3483aa27d33d..d80f16458f04d 100644 --- a/tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts +++ b/tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts @@ -7,3 +7,20 @@ type typeAlias2 = typeof varOfAliasedType2; function func(): typeAlias3 { return null; } var varOfAliasedType3 = func(); type typeAlias3 = typeof varOfAliasedType3; + +// Repro from #26104 + +interface Input { + a: number; + b: number; +} + +type R = ReturnType; +function mul(input: Input): R { + return input.a * input.b; +} + +// Repro from #26104 + +type R2 = ReturnType; +function f(): R2 { return 0; }