diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c89c78e83eb..806e46b84c7 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 e3774296e0d..b282484ab0c 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 20f5767d027..50e37c7983b 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 889797a64b0..c9f8851fcc8 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 7f746d2486c..87c0aa129b4 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 207f9efcfd3..b22bd7fb1cc 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 f6e339eab7f..b0bd677cf8d 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) {}