Merge pull request #26236 from Microsoft/fixCircularReturnType

Fix circular return type issue
This commit is contained in:
Anders Hejlsberg 2018-08-06 16:38:31 -07:00 committed by GitHub
commit eeb19c1e22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 269 additions and 113 deletions

View File

@ -7545,9 +7545,10 @@ namespace ts {
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>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<AccessorDeclaration>(getSymbolOfNode(declaration), SyntaxKind.SetAccessor);
return getAnnotatedAccessorType(setter);
}
const typeFromTag = getReturnTypeOfTypeTag(declaration);
if (typeFromTag) {
return typeFromTag;
}
if (nodeIsMissing((<FunctionLikeDeclaration>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(<FunctionLikeDeclaration>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((<FunctionLikeDeclaration>signature.declaration).body) ? anyType : getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration));
if (!popTypeResolution()) {
type = anyType;
if (noImplicitAny) {
const declaration = <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 = <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((<ClassDeclaration>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<AccessorDeclaration>(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(<FunctionExpression>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<SetAccessorDeclaration>(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((<ParenthesizedTypeNode | OptionalTypeNode>node).type);
case SyntaxKind.ThisType:
return checkThisType(<ThisTypeNode>node);
case SyntaxKind.TypeOperator:
return checkTypeOperator(<TypeOperatorNode>node);
case SyntaxKind.ConditionalType:

View File

@ -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

View File

@ -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<TypeParameterDeclaration> {

View File

@ -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<T>'.
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<void> { } // 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<T>'.
!!! error TS1055: Types of property 'then' are incompatible.

View File

@ -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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> type.
async function fn4(): number { } // error
~~~~~~
!!! error TS1064: The return type of an async function or method must be the global Promise<T> type.
~~~~~~
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
async function fn5(): PromiseLike<void> { } // error
~~~~~~~~~~~~~~~~~
!!! error TS1064: The return type of an async function or method must be the global Promise<T> type.

View File

@ -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} */

View File

@ -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<typeof mul>;
~
!!! 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<typeof f>;
~~
!!! error TS2456: Type alias 'R2' circularly references itself.
function f(): R2 { return 0; }
~~
!!! error TS2577: Return type annotation circularly references itself.

View File

@ -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<typeof mul>;
function mul(input: Input): R {
return input.a * input.b;
}
// Repro from #26104
type R2 = ReturnType<typeof f>;
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; }

View File

@ -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<typeof mul>;
>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<typeof f>;
>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))

View File

@ -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<typeof mul>;
>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<typeof f>;
>R2 : any
>f : () => any
function f(): R2 { return 0; }
>f : () => any
>0 : 0

View File

@ -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<L extends any[], U = (...args: L) => void> =
U extends (h: infer H, ...args: infer R) => [Promise<H>, ...PromisedTuple<R>] ? [] : []
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2577: Return type annotation circularly references itself.
~
!!! error TS2304: Cannot find name 'H'.
~~~~~~~~~~~~~~~~~~~

View File

@ -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;

View File

@ -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<typeof mul>;
function mul(input: Input): R {
return input.a * input.b;
}
// Repro from #26104
type R2 = ReturnType<typeof f>;
function f(): R2 { return 0; }