From c48e34ef91fa9428a6e4d69196fe299671efad9a Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 2 Jul 2019 17:06:42 -0700 Subject: [PATCH 1/9] Did you forget to use await? for operators --- src/compiler/checker.ts | 106 +++++++++++++----- src/compiler/diagnosticMessages.json | 40 +++++++ ...existentPropertyAvailableOnPromisedType.ts | 3 - .../operationsAvailableOnPromisedType.ts | 25 +++++ 4 files changed, 146 insertions(+), 28 deletions(-) delete mode 100644 tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts create mode 100644 tests/cases/compiler/operationsAvailableOnPromisedType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 610967cfc4f50..f4bee2eef4fc1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -932,6 +932,18 @@ namespace ts { addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : createDiagnosticForNodeFromMessageChain(location, message)); } + function errorAndMaybeSuggestAwait( + location: Node | undefined, + maybeMissingAwait: boolean, + defaultMessage: DiagnosticMessage, + missingAwaitMessage: DiagnosticMessage, + arg0?: string | number | undefined, arg1?: string | number | undefined, arg2?: string | number | undefined, arg3?: string | number | undefined): Diagnostic { + if (maybeMissingAwait) { + return error(location, missingAwaitMessage, arg0, arg1, arg2, arg3); + } + return error(location, defaultMessage, arg0, arg1, arg2, arg3); + } + function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) { symbolCount++; const symbol = (new Symbol(flags | SymbolFlags.Transient, name)); @@ -23662,9 +23674,14 @@ namespace ts { } } - function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean { + function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage, missingAwaitDiagnostic: DiagnosticMessage): boolean { if (!isTypeAssignableTo(type, numberOrBigIntType)) { - error(operand, diagnostic); + const awaitedType = getAwaitedType(type); + errorAndMaybeSuggestAwait( + operand, + !!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType), + diagnostic, + missingAwaitDiagnostic); return false; } return true; @@ -23862,7 +23879,8 @@ namespace ts { case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); + Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type, + Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access); @@ -23880,7 +23898,8 @@ namespace ts { const ok = checkArithmeticOperandType( node.operand, checkNonNullType(operandType, node.operand), - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); + Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type, + Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access); @@ -24272,8 +24291,8 @@ namespace ts { } else { // otherwise just check each operand separately and report errors as normal - const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type); - const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type); + const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); + const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); let resultType: Type; // If both are any or unknown, allow operation; assume it will resolve to number if ((isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) || @@ -24282,7 +24301,7 @@ namespace ts { ) { resultType = numberType; } - // At least one is assignable to bigint, so both should be only assignable to bigint + // At least one is assignable to bigint, so check that both are else if (isTypeAssignableToKind(leftType, TypeFlags.BigIntLike) && isTypeAssignableToKind(rightType, TypeFlags.BigIntLike)) { switch (operator) { case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: @@ -24291,8 +24310,9 @@ namespace ts { } resultType = bigintType; } + // Exactly one of leftType/rightType is assignable to bigint else { - reportOperatorError(); + reportOperatorError((awaitedLeft, awaitedRight) => isTypeAssignableToKind(awaitedLeft, TypeFlags.BigIntLike) && isTypeAssignableToKind(awaitedRight, TypeFlags.BigIntLike)); resultType = errorType; } if (leftOk && rightOk) { @@ -24337,7 +24357,14 @@ namespace ts { } if (!resultType) { - reportOperatorError(); + // Types that have a reasonably good chance of being a valid operand type. + // If both types have an awaited type of one of these, we’ll assume the user + // might be missing an await without doing an exhaustive check that inserting + // await(s) will actually be a completely valid binary expression. + const closeEnoughKind = TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.AnyOrUnknown; + reportOperatorError((awaitedLeft, awaitedRight) => + isTypeAssignableToKind(awaitedLeft, closeEnoughKind) && + isTypeAssignableToKind(awaitedRight, closeEnoughKind)); return anyType; } @@ -24352,21 +24379,18 @@ namespace ts { if (checkForDisallowedESSymbolOperand(operator)) { leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left)); rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right)); - if (!(isTypeComparableTo(leftType, rightType) || isTypeComparableTo(rightType, leftType) || - (isTypeAssignableTo(leftType, numberOrBigIntType) && isTypeAssignableTo(rightType, numberOrBigIntType)) - )) { - reportOperatorError(); - } + reportOperatorErrorUnless((left, right) => + isTypeComparableTo(left, right) || isTypeComparableTo(right, left) || ( + isTypeAssignableTo(left, numberOrBigIntType) && isTypeAssignableTo(right, numberOrBigIntType))); } return booleanType; case SyntaxKind.EqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.ExclamationEqualsEqualsToken: - if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) { - reportOperatorError(); - } + reportOperatorErrorUnless((left, right) => isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left)); return booleanType; + case SyntaxKind.InstanceOfKeyword: return checkInstanceOfExpression(left, right, leftType, rightType); case SyntaxKind.InKeyword: @@ -24493,13 +24517,33 @@ namespace ts { } } - function reportOperatorError() { - const [leftStr, rightStr] = getTypeNamesForErrorDisplay(leftType, rightType); + /** + * Returns true if an error is reported + */ + function reportOperatorErrorUnless(typesAreCompatible: (left: Type, right: Type) => boolean): boolean { + if (!typesAreCompatible(leftType, rightType)) { + reportOperatorError(typesAreCompatible); + return true; + } + return false; + } + + function reportOperatorError(awaitedTypesAreCompatible?: (left: Type, right: Type) => boolean) { + let wouldWorkWithAwait = false; const errNode = errorNode || operatorToken; - if (!tryGiveBetterPrimaryError(errNode, leftStr, rightStr)) { - error( + const [leftStr, rightStr] = getTypeNamesForErrorDisplay(leftType, rightType); + if (awaitedTypesAreCompatible) { + const awaitedLeftType = getAwaitedType(leftType); + const awaitedRightType = getAwaitedType(rightType); + wouldWorkWithAwait = !!(awaitedLeftType && awaitedRightType) && awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType); + } + + if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) { + errorAndMaybeSuggestAwait( errNode, + wouldWorkWithAwait, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, + Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2_Did_you_forget_to_use_await, tokenToString(operatorToken.kind), leftStr, rightStr, @@ -24507,15 +24551,27 @@ namespace ts { } } - function tryGiveBetterPrimaryError(errNode: Node, leftStr: string, rightStr: string) { + function tryGiveBetterPrimaryError(errNode: Node, maybeMissingAwait: boolean, leftStr: string, rightStr: string) { + let typeName: string | undefined; switch (operatorToken.kind) { case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.EqualsEqualsToken: - return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "false", leftStr, rightStr); + typeName = "true"; + break; case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: - return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "true", leftStr, rightStr); - } + typeName = "false"; + } + + if (typeName) { + return errorAndMaybeSuggestAwait( + errNode, + maybeMissingAwait, + Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, + Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap_Did_you_forget_to_use_await, + typeName, leftStr, rightStr); + } + return undefined; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3b426f2d0c6be..446d429427278 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2693,6 +2693,46 @@ "category": "Error", "code": 2772 }, + "Operator '{0}' cannot be applied to types '{1}' and '{2}'. Did you forget to use 'await'?": { + "category": "Error", + "code": 2773 + }, + "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { + "category": "Error", + "code": 2774 + }, + "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { + "category": "Error", + "code": 2775 + }, + "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { + "category": "Error", + "code": 2777 + }, + "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { + "category": "Error", + "code": 2777 + }, + "Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": { + "category": "Error", + "code": 2778 + }, + "Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": { + "category": "Error", + "code": 2779 + }, + "Type '{0}' has no call signatures. Did you forget to use 'await'?": { + "category": "Error", + "code": 2780 + }, + "Type '{0}' has no construct signatures. Did you forget to use 'await'?": { + "category": "Error", + "code": 2781 + }, + "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": { + "category": "Error", + "code": 2782 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts b/tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts deleted file mode 100644 index 476f4ac563617..0000000000000 --- a/tests/cases/compiler/nonexistentPropertyAvailableOnPromisedType.ts +++ /dev/null @@ -1,3 +0,0 @@ -function f(x: Promise) { - x.toLowerCase(); -} diff --git a/tests/cases/compiler/operationsAvailableOnPromisedType.ts b/tests/cases/compiler/operationsAvailableOnPromisedType.ts new file mode 100644 index 0000000000000..24e3f891fe4cd --- /dev/null +++ b/tests/cases/compiler/operationsAvailableOnPromisedType.ts @@ -0,0 +1,25 @@ +function fn( + a: number, + b: Promise, + c: Promise, + d: Promise<{ prop: string }>, + e: Promise<() => void>, + f: Promise<() => void> | (() => void), + g: Promise<{ new(): any }> +) { + // All errors + a | b; + b | a; + a + b; + a > b; + b++; + --b; + a === b; + for (const s of c) { + fn(b, b, c, d); + d.prop; + } + e(); + f(); + new g(); +} From 48fc6b8b1775b632c285c401d9487db5c89eff10 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 2 Jul 2019 18:04:55 -0700 Subject: [PATCH 2/9] Did you forget to use await? on iterables --- src/compiler/checker.ts | 33 ++++++++++++------- src/compiler/diagnosticMessages.json | 26 ++++++++++++--- .../operationsAvailableOnPromisedType.ts | 4 ++- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f4bee2eef4fc1..63fa0f7e88917 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27922,18 +27922,28 @@ namespace ts { // number and string input is allowed, we want to say that number is not an // array type or a string type. const yieldType = getIterationTypeOfIterable(use, IterationTypeKind.Yield, inputType, /*errorNode*/ undefined); - const diagnostic = !(use & IterationUse.AllowsStringInputFlag) || hasStringConstituent + const [defaultDiagnostic, missingAwaitDiagnostic]: [DiagnosticMessage, DiagnosticMessage | undefined] = !(use & IterationUse.AllowsStringInputFlag) || hasStringConstituent ? downlevelIteration - ? Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator + ? [Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await] : yieldType - ? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators - : Diagnostics.Type_0_is_not_an_array_type + ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined] + : [Diagnostics.Type_0_is_not_an_array_type, Diagnostics.Type_0_is_not_an_array_type_Did_you_forget_to_use_await] : downlevelIteration - ? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator + ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await] : yieldType - ? Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators - : Diagnostics.Type_0_is_not_an_array_type_or_a_string_type; - error(errorNode, diagnostic, typeToString(arrayType)); + ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined] + : [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Did_you_forget_to_use_await]; + if (missingAwaitDiagnostic) { + errorAndMaybeSuggestAwait( + errorNode, + !!getAwaitedTypeOfPromise(arrayType), + defaultDiagnostic, + missingAwaitDiagnostic, + typeToString(arrayType)); + } + else { + error(errorNode, defaultDiagnostic, typeToString(arrayType)); + } } return hasStringConstituent ? stringType : undefined; } @@ -28232,9 +28242,10 @@ namespace ts { } function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void { - error(errorNode, allowAsyncIterables - ? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator - : Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, typeToString(type)); + const [defaultDiagnostic, missingAwaitDiagnostic] = allowAsyncIterables + ? [Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator, Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_Did_you_forget_to_use_await] + : [Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await]; + errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), defaultDiagnostic, missingAwaitDiagnostic, typeToString(type)); } /** diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 446d429427278..a7b6283824975 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2713,26 +2713,42 @@ "category": "Error", "code": 2777 }, - "Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": { + "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'?": { "category": "Error", "code": 2778 }, - "Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": { + "Type '{0}' is not an array type. Did you forget to use 'await'?": { "category": "Error", "code": 2779 }, - "Type '{0}' has no call signatures. Did you forget to use 'await'?": { + "Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": { "category": "Error", "code": 2780 }, - "Type '{0}' has no construct signatures. Did you forget to use 'await'?": { + "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { "category": "Error", "code": 2781 }, - "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": { + "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { "category": "Error", "code": 2782 }, + "Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": { + "category": "Error", + "code": 2783 + }, + "Type '{0}' has no call signatures. Did you forget to use 'await'?": { + "category": "Error", + "code": 2784 + }, + "Type '{0}' has no construct signatures. Did you forget to use 'await'?": { + "category": "Error", + "code": 2785 + }, + "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": { + "category": "Error", + "code": 2786 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/cases/compiler/operationsAvailableOnPromisedType.ts b/tests/cases/compiler/operationsAvailableOnPromisedType.ts index 24e3f891fe4cd..76e2cea6dd8b1 100644 --- a/tests/cases/compiler/operationsAvailableOnPromisedType.ts +++ b/tests/cases/compiler/operationsAvailableOnPromisedType.ts @@ -1,4 +1,4 @@ -function fn( +async function fn( a: number, b: Promise, c: Promise, @@ -15,10 +15,12 @@ function fn( b++; --b; a === b; + [...c]; for (const s of c) { fn(b, b, c, d); d.prop; } + for await (const s of c) {} e(); f(); new g(); From a3a076d79f46bc52c6fc4e1ddbda90783568a07b Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 3 Jul 2019 09:33:03 -0700 Subject: [PATCH 3/9] Did you forget to use await? for call and construct signatures --- src/compiler/checker.ts | 8 +++-- src/compiler/diagnosticMessages.json | 30 ++++++++++++------- .../operationsAvailableOnPromisedType.ts | 1 + 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 63fa0f7e88917..1a99c2642fd72 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22342,6 +22342,8 @@ namespace ts { function invocationErrorDetails(apparentType: Type, kind: SignatureKind): DiagnosticMessageChain { let errorInfo: DiagnosticMessageChain | undefined; const isCall = kind === SignatureKind.Call; + const awaitedType = getAwaitedType(apparentType); + const mightWorkWithAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0; if (apparentType.flags & TypeFlags.Union) { const types = (apparentType as UnionType).types; let hasSignatures = false; @@ -22408,9 +22410,9 @@ namespace ts { } return chainDiagnosticMessages( errorInfo, - isCall ? - Diagnostics.This_expression_is_not_callable : - Diagnostics.This_expression_is_not_constructable + mightWorkWithAwait + ? isCall ? Diagnostics.This_expression_is_not_callable_Did_you_forget_to_use_await : Diagnostics.This_expression_is_not_constructable_Did_you_forget_to_use_await + : isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable ); } function invocationError(errorTarget: Node, apparentType: Type, kind: SignatureKind, relatedInformation?: DiagnosticRelatedInformation) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a7b6283824975..e3774296e0d49 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2705,49 +2705,57 @@ "category": "Error", "code": 2775 }, - "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { + "This expression is not callable. Did you forget to use 'await'?": { + "category": "Error", + "code": 2776 + }, + "This expression is not constructable. Did you forget to use 'await'?": { "category": "Error", "code": 2777 }, + "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { + "category": "Error", + "code": 2778 + }, "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { "category": "Error", - "code": 2777 + "code": 2779 }, "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'?": { "category": "Error", - "code": 2778 + "code": 2780 }, "Type '{0}' is not an array type. Did you forget to use 'await'?": { "category": "Error", - "code": 2779 + "code": 2781 }, "Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": { "category": "Error", - "code": 2780 + "code": 2782 }, "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { "category": "Error", - "code": 2781 + "code": 2783 }, "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { "category": "Error", - "code": 2782 + "code": 2784 }, "Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": { "category": "Error", - "code": 2783 + "code": 2785 }, "Type '{0}' has no call signatures. Did you forget to use 'await'?": { "category": "Error", - "code": 2784 + "code": 2786 }, "Type '{0}' has no construct signatures. Did you forget to use 'await'?": { "category": "Error", - "code": 2785 + "code": 2787 }, "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": { "category": "Error", - "code": 2786 + "code": 2788 }, "Import declaration '{0}' is using private name '{1}'.": { diff --git a/tests/cases/compiler/operationsAvailableOnPromisedType.ts b/tests/cases/compiler/operationsAvailableOnPromisedType.ts index 76e2cea6dd8b1..f6e339eab7f55 100644 --- a/tests/cases/compiler/operationsAvailableOnPromisedType.ts +++ b/tests/cases/compiler/operationsAvailableOnPromisedType.ts @@ -24,4 +24,5 @@ async function fn( e(); f(); new g(); + b(); } From e89a2c457139bb6d0c40058a4c8a6838f9c543f5 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 3 Jul 2019 10:49:09 -0700 Subject: [PATCH 4/9] Update baselines --- src/compiler/checker.ts | 8 +- ...erationsAvailableOnPromisedType.errors.txt | 91 +++++++++++ .../operationsAvailableOnPromisedType.js | 141 ++++++++++++++++++ .../operationsAvailableOnPromisedType.symbols | 94 ++++++++++++ .../operationsAvailableOnPromisedType.types | 104 +++++++++++++ .../types.asyncGenerators.es2018.2.errors.txt | 4 +- 6 files changed, 437 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt create mode 100644 tests/baselines/reference/operationsAvailableOnPromisedType.js create mode 100644 tests/baselines/reference/operationsAvailableOnPromisedType.symbols create mode 100644 tests/baselines/reference/operationsAvailableOnPromisedType.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1a99c2642fd72..c89c78e83eb98 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24537,7 +24537,9 @@ namespace ts { if (awaitedTypesAreCompatible) { const awaitedLeftType = getAwaitedType(leftType); const awaitedRightType = getAwaitedType(rightType); - wouldWorkWithAwait = !!(awaitedLeftType && awaitedRightType) && awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType); + wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType) + && !!(awaitedLeftType && awaitedRightType) + && awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType); } if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) { @@ -24558,11 +24560,11 @@ namespace ts { switch (operatorToken.kind) { case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.EqualsEqualsToken: - typeName = "true"; + typeName = "false"; break; case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: - typeName = "false"; + typeName = "true"; } if (typeName) { diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt new file mode 100644 index 0000000000000..20f5767d02719 --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt @@ -0,0 +1,91 @@ +tests/cases/compiler/operationsAvailableOnPromisedType.ts(11,9): error TS2766: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(12,5): error TS2765: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(13,5): error TS2763: Operator '+' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(14,5): error TS2763: Operator '>' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(15,5): error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(16,7): error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(17,5): error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(18,9): error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(19,21): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(20,9): error TS2554: Expected 7 arguments, but got 4. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(21,11): error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(23,27): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(24,5): error TS2774: This expression is not callable. Did you forget to use 'await'? + Type 'Promise<() => void>' has no call signatures. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(25,5): error TS2774: This expression is not callable. Did you forget to use 'await'? + Not all constituents of type 'Promise<() => void> | (() => void)' are callable. + Type 'Promise<() => void>' has no call signatures. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(26,9): error TS2775: This expression is not constructable. Did you forget to use 'await'? + Type 'Promise any>' has no construct signatures. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: This expression is not callable. + Type 'Promise' has no call signatures. + + +==== tests/cases/compiler/operationsAvailableOnPromisedType.ts (16 errors) ==== + async function fn( + a: number, + b: Promise, + c: Promise, + d: Promise<{ prop: string }>, + e: Promise<() => void>, + f: Promise<() => void> | (() => void), + g: Promise<{ new(): any }> + ) { + // All errors + a | b; + ~ +!!! error TS2766: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + b | a; + ~ +!!! error TS2765: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + a + b; + ~~~~~ +!!! error TS2763: Operator '+' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? + a > b; + ~~~~~ +!!! error TS2763: Operator '>' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? + b++; + ~ +!!! error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + --b; + ~ +!!! error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + a === b; + ~~~~~~~ +!!! error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? + [...c]; + ~ +!!! error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? + for (const s of c) { + ~ +!!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? + fn(b, b, c, d); + ~~~~~~~~~~~~~~ +!!! error TS2554: Expected 7 arguments, but got 4. +!!! related TS6210 tests/cases/compiler/operationsAvailableOnPromisedType.ts:6:5: An argument for 'e' was not provided. + d.prop; + ~~~~ +!!! error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? + } + for await (const s of c) {} + ~ +!!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? + e(); + ~ +!!! error TS2774: This expression is not callable. Did you forget to use 'await'? +!!! error TS2774: Type 'Promise<() => void>' has no call signatures. + f(); + ~ +!!! error TS2774: This expression is not callable. Did you forget to use 'await'? +!!! error TS2774: Not all constituents of type 'Promise<() => void> | (() => void)' are callable. +!!! error TS2774: Type 'Promise<() => void>' has no call signatures. + new g(); + ~ +!!! error TS2775: This expression is not constructable. Did you forget to use 'await'? +!!! error TS2775: Type 'Promise any>' has no construct signatures. + b(); + ~ +!!! error TS2349: This expression is not callable. +!!! error TS2349: Type 'Promise' has no call signatures. + } + \ No newline at end of file diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.js b/tests/baselines/reference/operationsAvailableOnPromisedType.js new file mode 100644 index 0000000000000..889797a64b059 --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.js @@ -0,0 +1,141 @@ +//// [operationsAvailableOnPromisedType.ts] +async function fn( + a: number, + b: Promise, + c: Promise, + d: Promise<{ prop: string }>, + e: Promise<() => void>, + f: Promise<() => void> | (() => void), + g: Promise<{ new(): any }> +) { + // All errors + a | b; + b | a; + a + b; + a > b; + b++; + --b; + a === b; + [...c]; + for (const s of c) { + fn(b, b, c, d); + d.prop; + } + for await (const s of c) {} + e(); + f(); + new g(); + b(); +} + + +//// [operationsAvailableOnPromisedType.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; +var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; +function fn(a, b, c, d, e, f, g) { + var c_1, c_1_1; + var e_1, _a; + return __awaiter(this, void 0, void 0, function () { + var _i, c_2, s, s, e_1_1; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + // All errors + a | b; + b | a; + a + b; + a > b; + b++; + --b; + a === b; + __spreadArrays(c); + for (_i = 0, c_2 = c; _i < c_2.length; _i++) { + s = c_2[_i]; + fn(b, b, c, d); + d.prop; + } + _b.label = 1; + case 1: + _b.trys.push([1, 6, 7, 12]); + c_1 = __asyncValues(c); + _b.label = 2; + case 2: return [4 /*yield*/, c_1.next()]; + case 3: + if (!(c_1_1 = _b.sent(), !c_1_1.done)) return [3 /*break*/, 5]; + s = c_1_1.value; + _b.label = 4; + case 4: return [3 /*break*/, 2]; + case 5: return [3 /*break*/, 12]; + case 6: + e_1_1 = _b.sent(); + e_1 = { error: e_1_1 }; + return [3 /*break*/, 12]; + case 7: + _b.trys.push([7, , 10, 11]); + if (!(c_1_1 && !c_1_1.done && (_a = c_1["return"]))) return [3 /*break*/, 9]; + return [4 /*yield*/, _a.call(c_1)]; + case 8: + _b.sent(); + _b.label = 9; + case 9: return [3 /*break*/, 11]; + case 10: + if (e_1) throw e_1.error; + return [7 /*endfinally*/]; + case 11: return [7 /*endfinally*/]; + case 12: + e(); + f(); + new g(); + b(); + return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.symbols b/tests/baselines/reference/operationsAvailableOnPromisedType.symbols new file mode 100644 index 0000000000000..7f746d2486ca7 --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.symbols @@ -0,0 +1,94 @@ +=== tests/cases/compiler/operationsAvailableOnPromisedType.ts === +async function fn( +>fn : Symbol(fn, Decl(operationsAvailableOnPromisedType.ts, 0, 0)) + + a: number, +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) + + b: Promise, +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + c: Promise, +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + d: Promise<{ prop: string }>, +>d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>prop : Symbol(prop, Decl(operationsAvailableOnPromisedType.ts, 4, 16)) + + e: Promise<() => void>, +>e : Symbol(e, Decl(operationsAvailableOnPromisedType.ts, 4, 33)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + f: Promise<() => void> | (() => void), +>f : Symbol(f, Decl(operationsAvailableOnPromisedType.ts, 5, 27)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + g: Promise<{ new(): any }> +>g : Symbol(g, Decl(operationsAvailableOnPromisedType.ts, 6, 42)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + +) { + // All errors + a | b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + b | a; +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) + + a + b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + a > b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + b++; +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + --b; +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + a === b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + [...c]; +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) + + for (const s of c) { +>s : Symbol(s, Decl(operationsAvailableOnPromisedType.ts, 18, 14)) +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) + + fn(b, b, c, d); +>fn : Symbol(fn, Decl(operationsAvailableOnPromisedType.ts, 0, 0)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) +>d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) + + d.prop; +>d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) + } + for await (const s of c) {} +>s : Symbol(s, Decl(operationsAvailableOnPromisedType.ts, 22, 20)) +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) + + e(); +>e : Symbol(e, Decl(operationsAvailableOnPromisedType.ts, 4, 33)) + + f(); +>f : Symbol(f, Decl(operationsAvailableOnPromisedType.ts, 5, 27)) + + new g(); +>g : Symbol(g, Decl(operationsAvailableOnPromisedType.ts, 6, 42)) + + b(); +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +} + diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.types b/tests/baselines/reference/operationsAvailableOnPromisedType.types new file mode 100644 index 0000000000000..207f9efcfd34a --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.types @@ -0,0 +1,104 @@ +=== tests/cases/compiler/operationsAvailableOnPromisedType.ts === +async function fn( +>fn : (a: number, b: Promise, c: Promise, d: Promise<{ prop: string; }>, e: Promise<() => void>, f: Promise<() => void> | (() => void), g: Promise any>) => Promise + + a: number, +>a : number + + b: Promise, +>b : Promise + + c: Promise, +>c : Promise + + d: Promise<{ prop: string }>, +>d : Promise<{ prop: string; }> +>prop : string + + e: Promise<() => void>, +>e : Promise<() => void> + + f: Promise<() => void> | (() => void), +>f : Promise<() => void> | (() => void) + + g: Promise<{ new(): any }> +>g : Promise any> + +) { + // All errors + a | b; +>a | b : number +>a : number +>b : Promise + + b | a; +>b | a : number +>b : Promise +>a : number + + a + b; +>a + b : any +>a : number +>b : Promise + + a > b; +>a > b : boolean +>a : number +>b : Promise + + b++; +>b++ : number +>b : Promise + + --b; +>--b : number +>b : Promise + + a === b; +>a === b : boolean +>a : number +>b : Promise + + [...c]; +>[...c] : any[] +>...c : any +>c : Promise + + for (const s of c) { +>s : any +>c : Promise + + fn(b, b, c, d); +>fn(b, b, c, d) : Promise +>fn : (a: number, b: Promise, c: Promise, d: Promise<{ prop: string; }>, e: Promise<() => void>, f: Promise<() => void> | (() => void), g: Promise any>) => Promise +>b : Promise +>b : Promise +>c : Promise +>d : Promise<{ prop: string; }> + + d.prop; +>d.prop : any +>d : Promise<{ prop: string; }> +>prop : any + } + for await (const s of c) {} +>s : any +>c : Promise + + e(); +>e() : any +>e : Promise<() => void> + + f(); +>f() : any +>f : Promise<() => void> | (() => void) + + new g(); +>new g() : any +>g : Promise any> + + b(); +>b() : any +>b : Promise +} + diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index c8c4ed39ed7e1..b00f35c503f14 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(2,12): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. -tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(8,12): error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. +tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(8,12): error TS2780: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'? tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(10,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. Types of property 'next' are incompatible. @@ -71,7 +71,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( async function * inferReturnType3() { yield* Promise.resolve([1, 2]); ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. +!!! error TS2780: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'? } const assignability1: () => AsyncIterableIterator = async function * () { ~~~~~~~~~~~~~~ From 094a001982b2180b933da03eb092fc2b889cb781 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 3 Jul 2019 16:04:09 -0700 Subject: [PATCH 5/9] Did you forget to use await? on arguments of function calls --- src/compiler/checker.ts | 11 +++++++++++ src/compiler/diagnosticMessages.json | 4 ++++ .../operationsAvailableOnPromisedType.errors.txt | 10 +++++----- .../reference/operationsAvailableOnPromisedType.js | 4 ++-- .../operationsAvailableOnPromisedType.symbols | 5 ++++- .../reference/operationsAvailableOnPromisedType.types | 7 +++++-- .../compiler/operationsAvailableOnPromisedType.ts | 2 +- 7 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c89c78e83eb98..806e46b84c7a8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21434,6 +21434,7 @@ namespace ts { const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType; if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, errorOutputContainer)) { Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors"); + maybeAddMissingAwaitInfo(arg, checkArgType, paramType); return errorOutputContainer.errors || []; } } @@ -21443,10 +21444,20 @@ namespace ts { const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined; if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) { Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors"); + maybeAddMissingAwaitInfo(errorNode, spreadType, restType); return errorOutputContainer.errors || []; } } return undefined; + + function maybeAddMissingAwaitInfo(errorNode: Node | undefined, source: Type, target: Type) { + if (errorNode && reportErrors && errorOutputContainer.errors && errorOutputContainer.errors.length) { + const awaitedTypeOfSource = getAwaitedTypeOfPromise(source); + if (awaitedTypeOfSource && isTypeRelatedTo(awaitedTypeOfSource, target, relation)) { + addRelatedInfo(errorOutputContainer.errors[0], createDiagnosticForNode(errorNode, Diagnostics.Did_you_forget_to_use_await)); + } + } + } } /** diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e3774296e0d49..b282484ab0ca8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2757,6 +2757,10 @@ "category": "Error", "code": 2788 }, + "Did you forget to use 'await'?": { + "category": "Error", + "code": 2789 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt index 20f5767d02719..50e37c7983b93 100644 --- a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt @@ -7,7 +7,7 @@ tests/cases/compiler/operationsAvailableOnPromisedType.ts(16,7): error TS2764: A tests/cases/compiler/operationsAvailableOnPromisedType.ts(17,5): error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? tests/cases/compiler/operationsAvailableOnPromisedType.ts(18,9): error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? tests/cases/compiler/operationsAvailableOnPromisedType.ts(19,21): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(20,9): error TS2554: Expected 7 arguments, but got 4. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(20,12): error TS2345: Argument of type 'Promise' is not assignable to parameter of type 'number'. tests/cases/compiler/operationsAvailableOnPromisedType.ts(21,11): error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? tests/cases/compiler/operationsAvailableOnPromisedType.ts(23,27): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? tests/cases/compiler/operationsAvailableOnPromisedType.ts(24,5): error TS2774: This expression is not callable. Did you forget to use 'await'? @@ -59,10 +59,10 @@ tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: T for (const s of c) { ~ !!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? - fn(b, b, c, d); - ~~~~~~~~~~~~~~ -!!! error TS2554: Expected 7 arguments, but got 4. -!!! related TS6210 tests/cases/compiler/operationsAvailableOnPromisedType.ts:6:5: An argument for 'e' was not provided. + fn(b, b, c, d, e, f, g); + ~ +!!! error TS2345: Argument of type 'Promise' is not assignable to parameter of type 'number'. +!!! related TS2777 tests/cases/compiler/operationsAvailableOnPromisedType.ts:20:12: Did you forget to use 'await'? d.prop; ~~~~ !!! error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.js b/tests/baselines/reference/operationsAvailableOnPromisedType.js index 889797a64b059..c9f8851fcc860 100644 --- a/tests/baselines/reference/operationsAvailableOnPromisedType.js +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.js @@ -18,7 +18,7 @@ async function fn( a === b; [...c]; for (const s of c) { - fn(b, b, c, d); + fn(b, b, c, d, e, f, g); d.prop; } for await (const s of c) {} @@ -98,7 +98,7 @@ function fn(a, b, c, d, e, f, g) { __spreadArrays(c); for (_i = 0, c_2 = c; _i < c_2.length; _i++) { s = c_2[_i]; - fn(b, b, c, d); + fn(b, b, c, d, e, f, g); d.prop; } _b.label = 1; diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.symbols b/tests/baselines/reference/operationsAvailableOnPromisedType.symbols index 7f746d2486ca7..87c0aa129b490 100644 --- a/tests/baselines/reference/operationsAvailableOnPromisedType.symbols +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.symbols @@ -65,12 +65,15 @@ async function fn( >s : Symbol(s, Decl(operationsAvailableOnPromisedType.ts, 18, 14)) >c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) - fn(b, b, c, d); + fn(b, b, c, d, e, f, g); >fn : Symbol(fn, Decl(operationsAvailableOnPromisedType.ts, 0, 0)) >b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) >b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) >c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) >d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) +>e : Symbol(e, Decl(operationsAvailableOnPromisedType.ts, 4, 33)) +>f : Symbol(f, Decl(operationsAvailableOnPromisedType.ts, 5, 27)) +>g : Symbol(g, Decl(operationsAvailableOnPromisedType.ts, 6, 42)) d.prop; >d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.types b/tests/baselines/reference/operationsAvailableOnPromisedType.types index 207f9efcfd34a..b22bd7fb1ccb6 100644 --- a/tests/baselines/reference/operationsAvailableOnPromisedType.types +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.types @@ -68,13 +68,16 @@ async function fn( >s : any >c : Promise - fn(b, b, c, d); ->fn(b, b, c, d) : Promise + fn(b, b, c, d, e, f, g); +>fn(b, b, c, d, e, f, g) : Promise >fn : (a: number, b: Promise, c: Promise, d: Promise<{ prop: string; }>, e: Promise<() => void>, f: Promise<() => void> | (() => void), g: Promise any>) => Promise >b : Promise >b : Promise >c : Promise >d : Promise<{ prop: string; }> +>e : Promise<() => void> +>f : Promise<() => void> | (() => void) +>g : Promise any> d.prop; >d.prop : any diff --git a/tests/cases/compiler/operationsAvailableOnPromisedType.ts b/tests/cases/compiler/operationsAvailableOnPromisedType.ts index f6e339eab7f55..b0bd677cf8dbd 100644 --- a/tests/cases/compiler/operationsAvailableOnPromisedType.ts +++ b/tests/cases/compiler/operationsAvailableOnPromisedType.ts @@ -17,7 +17,7 @@ async function fn( a === b; [...c]; for (const s of c) { - fn(b, b, c, d); + fn(b, b, c, d, e, f, g); d.prop; } for await (const s of c) {} From eb6b87aa2617416588392e6c1ac5f665400dbefd Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 3 Jul 2019 16:53:26 -0700 Subject: [PATCH 6/9] Refactor to use related info everywhere --- src/compiler/checker.ts | 98 +++++++++---------- src/compiler/diagnosticMessages.json | 3 +- ...erationsAvailableOnPromisedType.errors.txt | 75 ++++++++------ .../types.asyncGenerators.es2018.2.errors.txt | 5 +- 4 files changed, 96 insertions(+), 85 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 806e46b84c7a8..471a2c56742a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -933,15 +933,16 @@ namespace ts { } function errorAndMaybeSuggestAwait( - location: Node | undefined, + location: Node, maybeMissingAwait: boolean, - defaultMessage: DiagnosticMessage, - missingAwaitMessage: DiagnosticMessage, + message: DiagnosticMessage, arg0?: string | number | undefined, arg1?: string | number | undefined, arg2?: string | number | undefined, arg3?: string | number | undefined): Diagnostic { + const diagnostic = error(location, message, arg0, arg1, arg2, arg3); if (maybeMissingAwait) { - return error(location, missingAwaitMessage, arg0, arg1, arg2, arg3); + const related = createDiagnosticForNode(location, Diagnostics.Did_you_forget_to_use_await); + addRelatedInfo(diagnostic, related); } - return error(location, defaultMessage, arg0, arg1, arg2, arg3); + return diagnostic; } function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) { @@ -22350,11 +22351,11 @@ namespace ts { return true; } - function invocationErrorDetails(apparentType: Type, kind: SignatureKind): DiagnosticMessageChain { + function invocationErrorDetails(apparentType: Type, kind: SignatureKind): { messageChain: DiagnosticMessageChain, relatedMessage: DiagnosticMessage | undefined } { let errorInfo: DiagnosticMessageChain | undefined; const isCall = kind === SignatureKind.Call; const awaitedType = getAwaitedType(apparentType); - const mightWorkWithAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0; + const maybeMissingAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0; if (apparentType.flags & TypeFlags.Union) { const types = (apparentType as UnionType).types; let hasSignatures = false; @@ -22419,15 +22420,20 @@ namespace ts { typeToString(apparentType) ); } - return chainDiagnosticMessages( - errorInfo, - mightWorkWithAwait - ? isCall ? Diagnostics.This_expression_is_not_callable_Did_you_forget_to_use_await : Diagnostics.This_expression_is_not_constructable_Did_you_forget_to_use_await - : isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable - ); + return { + messageChain: chainDiagnosticMessages( + errorInfo, + isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable + ), + relatedMessage: maybeMissingAwait ? Diagnostics.Did_you_forget_to_use_await : undefined, + }; } function invocationError(errorTarget: Node, apparentType: Type, kind: SignatureKind, relatedInformation?: DiagnosticRelatedInformation) { - const diagnostic = createDiagnosticForNodeFromMessageChain(errorTarget, invocationErrorDetails(apparentType, kind)); + const { messageChain, relatedMessage: relatedInfo } = invocationErrorDetails(apparentType, kind); + const diagnostic = createDiagnosticForNodeFromMessageChain(errorTarget, messageChain); + if (relatedInfo) { + addRelatedInfo(diagnostic, createDiagnosticForNode(errorTarget, relatedInfo)); + } if (isCallExpression(errorTarget.parent)) { const { start, length } = getDiagnosticSpanForCallNode(errorTarget.parent, /* doNotIncludeArguments */ true); diagnostic.start = start; @@ -22527,9 +22533,12 @@ namespace ts { const headMessage = getDiagnosticHeadMessageForDecoratorResolution(node); if (!callSignatures.length) { - let errorInfo = invocationErrorDetails(apparentType, SignatureKind.Call); - errorInfo = chainDiagnosticMessages(errorInfo, headMessage); - const diag = createDiagnosticForNodeFromMessageChain(node.expression, errorInfo); + const errorDetails = invocationErrorDetails(apparentType, SignatureKind.Call); + const messageChain = chainDiagnosticMessages(errorDetails.messageChain, headMessage); + const diag = createDiagnosticForNodeFromMessageChain(node.expression, messageChain); + if (errorDetails.relatedMessage) { + addRelatedInfo(diag, createDiagnosticForNode(node.expression, errorDetails.relatedMessage)); + } diagnostics.add(diag); invocationErrorRecovery(apparentType, SignatureKind.Call, diag); return resolveErrorCall(node); @@ -23687,14 +23696,13 @@ namespace ts { } } - function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage, missingAwaitDiagnostic: DiagnosticMessage): boolean { + function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean { if (!isTypeAssignableTo(type, numberOrBigIntType)) { const awaitedType = getAwaitedType(type); errorAndMaybeSuggestAwait( operand, !!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType), - diagnostic, - missingAwaitDiagnostic); + diagnostic); return false; } return true; @@ -23892,8 +23900,7 @@ namespace ts { case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type, - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); + Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access); @@ -23911,8 +23918,7 @@ namespace ts { const ok = checkArithmeticOperandType( node.operand, checkNonNullType(operandType, node.operand), - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type, - Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); + Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access); @@ -24304,8 +24310,8 @@ namespace ts { } else { // otherwise just check each operand separately and report errors as normal - const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); - const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await); + const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type); + const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type); let resultType: Type; // If both are any or unknown, allow operation; assume it will resolve to number if ((isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) || @@ -24558,7 +24564,6 @@ namespace ts { errNode, wouldWorkWithAwait, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, - Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2_Did_you_forget_to_use_await, tokenToString(operatorToken.kind), leftStr, rightStr, @@ -24583,7 +24588,6 @@ namespace ts { errNode, maybeMissingAwait, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, - Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap_Did_you_forget_to_use_await, typeName, leftStr, rightStr); } @@ -27937,28 +27941,22 @@ namespace ts { // number and string input is allowed, we want to say that number is not an // array type or a string type. const yieldType = getIterationTypeOfIterable(use, IterationTypeKind.Yield, inputType, /*errorNode*/ undefined); - const [defaultDiagnostic, missingAwaitDiagnostic]: [DiagnosticMessage, DiagnosticMessage | undefined] = !(use & IterationUse.AllowsStringInputFlag) || hasStringConstituent + const [defaultDiagnostic, maybeMissingAwait]: [DiagnosticMessage, boolean] = !(use & IterationUse.AllowsStringInputFlag) || hasStringConstituent ? downlevelIteration - ? [Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await] + ? [Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true] : yieldType - ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined] - : [Diagnostics.Type_0_is_not_an_array_type, Diagnostics.Type_0_is_not_an_array_type_Did_you_forget_to_use_await] + ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false] + : [Diagnostics.Type_0_is_not_an_array_type, true] : downlevelIteration - ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await] + ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true] : yieldType - ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined] - : [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Did_you_forget_to_use_await]; - if (missingAwaitDiagnostic) { - errorAndMaybeSuggestAwait( - errorNode, - !!getAwaitedTypeOfPromise(arrayType), - defaultDiagnostic, - missingAwaitDiagnostic, - typeToString(arrayType)); - } - else { - error(errorNode, defaultDiagnostic, typeToString(arrayType)); - } + ? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false] + : [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, true]; + errorAndMaybeSuggestAwait( + errorNode, + maybeMissingAwait && !!getAwaitedTypeOfPromise(arrayType), + defaultDiagnostic, + typeToString(arrayType)); } return hasStringConstituent ? stringType : undefined; } @@ -28257,10 +28255,10 @@ namespace ts { } function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void { - const [defaultDiagnostic, missingAwaitDiagnostic] = allowAsyncIterables - ? [Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator, Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_Did_you_forget_to_use_await] - : [Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await]; - errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), defaultDiagnostic, missingAwaitDiagnostic, typeToString(type)); + const message = allowAsyncIterables + ? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator + : Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator; + errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type)); } /** diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b282484ab0ca8..f2c5d3805d7ab 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2655,8 +2655,7 @@ }, "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'.": { "category": "Error", - "code": 2763 - }, + "code": 77 }, "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'.": { "category": "Error", "code": 2764 diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt index 50e37c7983b93..955bb3c295107 100644 --- a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt @@ -1,21 +1,21 @@ -tests/cases/compiler/operationsAvailableOnPromisedType.ts(11,9): error TS2766: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(12,5): error TS2765: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(13,5): error TS2763: Operator '+' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(14,5): error TS2763: Operator '>' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(15,5): error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(16,7): error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(17,5): error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(18,9): error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(19,21): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(11,9): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(12,5): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(13,5): error TS2365: Operator '+' cannot be applied to types 'number' and 'Promise'. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(14,5): error TS2365: Operator '>' cannot be applied to types 'number' and 'Promise'. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(15,5): error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(16,7): error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(17,5): error TS2367: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(18,9): error TS2461: Type 'Promise' is not an array type. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(19,21): error TS2495: Type 'Promise' is not an array type or a string type. tests/cases/compiler/operationsAvailableOnPromisedType.ts(20,12): error TS2345: Argument of type 'Promise' is not assignable to parameter of type 'number'. tests/cases/compiler/operationsAvailableOnPromisedType.ts(21,11): error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(23,27): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? -tests/cases/compiler/operationsAvailableOnPromisedType.ts(24,5): error TS2774: This expression is not callable. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(23,27): error TS2495: Type 'Promise' is not an array type or a string type. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(24,5): error TS2349: This expression is not callable. Type 'Promise<() => void>' has no call signatures. -tests/cases/compiler/operationsAvailableOnPromisedType.ts(25,5): error TS2774: This expression is not callable. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(25,5): error TS2349: This expression is not callable. Not all constituents of type 'Promise<() => void> | (() => void)' are callable. Type 'Promise<() => void>' has no call signatures. -tests/cases/compiler/operationsAvailableOnPromisedType.ts(26,9): error TS2775: This expression is not constructable. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(26,9): error TS2351: This expression is not constructable. Type 'Promise any>' has no construct signatures. tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: This expression is not callable. Type 'Promise' has no call signatures. @@ -34,55 +34,68 @@ tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: T // All errors a | b; ~ -!!! error TS2766: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:11:9: Did you forget to use 'await'? b | a; ~ -!!! error TS2765: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:12:5: Did you forget to use 'await'? a + b; ~~~~~ -!!! error TS2763: Operator '+' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? +!!! error TS2365: Operator '+' cannot be applied to types 'number' and 'Promise'. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:13:5: Did you forget to use 'await'? a > b; ~~~~~ -!!! error TS2763: Operator '>' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? +!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'Promise'. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:14:5: Did you forget to use 'await'? b++; ~ -!!! error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +!!! error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:15:5: Did you forget to use 'await'? --b; ~ -!!! error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +!!! error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:16:7: Did you forget to use 'await'? a === b; ~~~~~~~ -!!! error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? +!!! error TS2367: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:17:5: Did you forget to use 'await'? [...c]; ~ -!!! error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? +!!! error TS2461: Type 'Promise' is not an array type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:18:9: Did you forget to use 'await'? for (const s of c) { ~ -!!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +!!! error TS2495: Type 'Promise' is not an array type or a string type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:19:21: Did you forget to use 'await'? fn(b, b, c, d, e, f, g); ~ !!! error TS2345: Argument of type 'Promise' is not assignable to parameter of type 'number'. -!!! related TS2777 tests/cases/compiler/operationsAvailableOnPromisedType.ts:20:12: Did you forget to use 'await'? +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:20:12: Did you forget to use 'await'? d.prop; ~~~~ !!! error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? } for await (const s of c) {} ~ -!!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +!!! error TS2495: Type 'Promise' is not an array type or a string type. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:23:27: Did you forget to use 'await'? e(); ~ -!!! error TS2774: This expression is not callable. Did you forget to use 'await'? -!!! error TS2774: Type 'Promise<() => void>' has no call signatures. +!!! error TS2349: This expression is not callable. +!!! error TS2349: Type 'Promise<() => void>' has no call signatures. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:24:5: Did you forget to use 'await'? f(); ~ -!!! error TS2774: This expression is not callable. Did you forget to use 'await'? -!!! error TS2774: Not all constituents of type 'Promise<() => void> | (() => void)' are callable. -!!! error TS2774: Type 'Promise<() => void>' has no call signatures. +!!! error TS2349: This expression is not callable. +!!! error TS2349: Not all constituents of type 'Promise<() => void> | (() => void)' are callable. +!!! error TS2349: Type 'Promise<() => void>' has no call signatures. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:25:5: Did you forget to use 'await'? new g(); ~ -!!! error TS2775: This expression is not constructable. Did you forget to use 'await'? -!!! error TS2775: Type 'Promise any>' has no construct signatures. +!!! error TS2351: This expression is not constructable. +!!! error TS2351: Type 'Promise any>' has no construct signatures. +!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:26:9: Did you forget to use 'await'? b(); ~ !!! error TS2349: This expression is not callable. diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index b00f35c503f14..2b214fe3d4b2d 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(2,12): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. -tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(8,12): error TS2780: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'? +tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(8,12): error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(10,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. Types of property 'next' are incompatible. @@ -71,7 +71,8 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( async function * inferReturnType3() { yield* Promise.resolve([1, 2]); ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2780: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'? +!!! error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. +!!! related TS2789 tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts:8:12: Did you forget to use 'await'? } const assignability1: () => AsyncIterableIterator = async function * () { ~~~~~~~~~~~~~~ From 6626a99f1190d0a432b81671c4249434c64b02ec Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 8 Jul 2019 14:44:57 -0700 Subject: [PATCH 7/9] Fix bad rebase --- src/compiler/diagnosticMessages.json | 69 ++-------------------------- 1 file changed, 3 insertions(+), 66 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f2c5d3805d7ab..c2585e6b40b87 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2655,7 +2655,8 @@ }, "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'.": { "category": "Error", - "code": 77 }, + "code": 2673 + }, "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'.": { "category": "Error", "code": 2764 @@ -2692,73 +2693,9 @@ "category": "Error", "code": 2772 }, - "Operator '{0}' cannot be applied to types '{1}' and '{2}'. Did you forget to use 'await'?": { - "category": "Error", - "code": 2773 - }, - "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { - "category": "Error", - "code": 2774 - }, - "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { - "category": "Error", - "code": 2775 - }, - "This expression is not callable. Did you forget to use 'await'?": { - "category": "Error", - "code": 2776 - }, - "This expression is not constructable. Did you forget to use 'await'?": { - "category": "Error", - "code": 2777 - }, - "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": { - "category": "Error", - "code": 2778 - }, - "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { - "category": "Error", - "code": 2779 - }, - "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'?": { - "category": "Error", - "code": 2780 - }, - "Type '{0}' is not an array type. Did you forget to use 'await'?": { - "category": "Error", - "code": 2781 - }, - "Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": { - "category": "Error", - "code": 2782 - }, - "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { - "category": "Error", - "code": 2783 - }, - "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": { - "category": "Error", - "code": 2784 - }, - "Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": { - "category": "Error", - "code": 2785 - }, - "Type '{0}' has no call signatures. Did you forget to use 'await'?": { - "category": "Error", - "code": 2786 - }, - "Type '{0}' has no construct signatures. Did you forget to use 'await'?": { - "category": "Error", - "code": 2787 - }, - "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": { - "category": "Error", - "code": 2788 - }, "Did you forget to use 'await'?": { "category": "Error", - "code": 2789 + "code": 2773 }, "Import declaration '{0}' is using private name '{1}'.": { From 64501996cc0816e98d6fce343c8d48074809b790 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 8 Jul 2019 14:46:20 -0700 Subject: [PATCH 8/9] Update error code --- src/compiler/diagnosticMessages.json | 2 +- ...erationsAvailableOnPromisedType.errors.txt | 28 +++++++++---------- .../types.asyncGenerators.es2018.2.errors.txt | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c2585e6b40b87..c3396a70731a7 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2655,7 +2655,7 @@ }, "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'.": { "category": "Error", - "code": 2673 + "code": 2763 }, "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'.": { "category": "Error", diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt index 955bb3c295107..0fc56b82c1de6 100644 --- a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt @@ -35,43 +35,43 @@ tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: T a | b; ~ !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:11:9: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:11:9: Did you forget to use 'await'? b | a; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:12:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:12:5: Did you forget to use 'await'? a + b; ~~~~~ !!! error TS2365: Operator '+' cannot be applied to types 'number' and 'Promise'. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:13:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:13:5: Did you forget to use 'await'? a > b; ~~~~~ !!! error TS2365: Operator '>' cannot be applied to types 'number' and 'Promise'. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:14:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:14:5: Did you forget to use 'await'? b++; ~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:15:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:15:5: Did you forget to use 'await'? --b; ~ !!! error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:16:7: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:16:7: Did you forget to use 'await'? a === b; ~~~~~~~ !!! error TS2367: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:17:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:17:5: Did you forget to use 'await'? [...c]; ~ !!! error TS2461: Type 'Promise' is not an array type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:18:9: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:18:9: Did you forget to use 'await'? for (const s of c) { ~ !!! error TS2495: Type 'Promise' is not an array type or a string type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:19:21: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:19:21: Did you forget to use 'await'? fn(b, b, c, d, e, f, g); ~ !!! error TS2345: Argument of type 'Promise' is not assignable to parameter of type 'number'. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:20:12: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:20:12: Did you forget to use 'await'? d.prop; ~~~~ !!! error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? @@ -79,23 +79,23 @@ tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: T for await (const s of c) {} ~ !!! error TS2495: Type 'Promise' is not an array type or a string type. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:23:27: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:23:27: Did you forget to use 'await'? e(); ~ !!! error TS2349: This expression is not callable. !!! error TS2349: Type 'Promise<() => void>' has no call signatures. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:24:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:24:5: Did you forget to use 'await'? f(); ~ !!! error TS2349: This expression is not callable. !!! error TS2349: Not all constituents of type 'Promise<() => void> | (() => void)' are callable. !!! error TS2349: Type 'Promise<() => void>' has no call signatures. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:25:5: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:25:5: Did you forget to use 'await'? new g(); ~ !!! error TS2351: This expression is not constructable. !!! error TS2351: Type 'Promise any>' has no construct signatures. -!!! related TS2763 tests/cases/compiler/operationsAvailableOnPromisedType.ts:26:9: Did you forget to use 'await'? +!!! related TS2773 tests/cases/compiler/operationsAvailableOnPromisedType.ts:26:9: Did you forget to use 'await'? b(); ~ !!! error TS2349: This expression is not callable. diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index 2b214fe3d4b2d..1ca77aebc86fe 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -72,7 +72,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( yield* Promise.resolve([1, 2]); ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. -!!! related TS2789 tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts:8:12: Did you forget to use 'await'? +!!! related TS2773 tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts:8:12: Did you forget to use 'await'? } const assignability1: () => AsyncIterableIterator = async function * () { ~~~~~~~~~~~~~~ From bdd8a3e8786426128e10f9778de1a2cdfd2de1d5 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 8 Jul 2019 16:32:53 -0700 Subject: [PATCH 9/9] Only add "Did you forget await" for function args when the parameter type is not promise-like --- src/compiler/checker.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 471a2c56742a2..943eb2f3df575 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21453,6 +21453,10 @@ namespace ts { function maybeAddMissingAwaitInfo(errorNode: Node | undefined, source: Type, target: Type) { if (errorNode && reportErrors && errorOutputContainer.errors && errorOutputContainer.errors.length) { + // Bail if target is Promise-like---something else is wrong + if (getAwaitedTypeOfPromise(target)) { + return; + } const awaitedTypeOfSource = getAwaitedTypeOfPromise(source); if (awaitedTypeOfSource && isTypeRelatedTo(awaitedTypeOfSource, target, relation)) { addRelatedInfo(errorOutputContainer.errors[0], createDiagnosticForNode(errorNode, Diagnostics.Did_you_forget_to_use_await));