diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ecb7fe57c8..76e11d53811 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22544,6 +22544,11 @@ namespace ts { case "BigInt64Array": case "BigUint64Array": return Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_1_or_later; + case "await": + if (isCallExpression(node.parent)) { + return Diagnostics.Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function; + } + // falls through default: if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { return Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 606dc1a2acb..17e8a5550f2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1491,6 +1491,10 @@ "category": "Error", "code": 2310 }, + "Cannot find name '{0}'. Did you mean to write this in an async function?": { + "category": "Error", + "code": 2311 + }, "An interface can only extend an object type or intersection of object types with statically known members.": { "category": "Error", "code": 2312 diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index be93c1d711b..085b2febcdf 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -4,6 +4,7 @@ namespace ts.codefix { const errorCodes = [ Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, Diagnostics.for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code, + Diagnostics.Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function.code ]; registerCodeFix({ errorCodes, diff --git a/tests/baselines/reference/awaitCallExpressionInSyncFunction.errors.txt b/tests/baselines/reference/awaitCallExpressionInSyncFunction.errors.txt new file mode 100644 index 00000000000..51d7f4d4694 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpressionInSyncFunction.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/awaitCallExpressionInSyncFunction.ts(2,16): error TS2311: Cannot find name 'await'. Did you mean to write this in an async function? + + +==== tests/cases/compiler/awaitCallExpressionInSyncFunction.ts (1 errors) ==== + function foo() { + const foo = await(Promise.resolve(1)); + ~~~~~ +!!! error TS2311: Cannot find name 'await'. Did you mean to write this in an async function? + return foo; + } + \ No newline at end of file diff --git a/tests/baselines/reference/awaitCallExpressionInSyncFunction.js b/tests/baselines/reference/awaitCallExpressionInSyncFunction.js new file mode 100644 index 00000000000..2fef4c398d4 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpressionInSyncFunction.js @@ -0,0 +1,12 @@ +//// [awaitCallExpressionInSyncFunction.ts] +function foo() { + const foo = await(Promise.resolve(1)); + return foo; +} + + +//// [awaitCallExpressionInSyncFunction.js] +function foo() { + const foo = await(Promise.resolve(1)); + return foo; +} diff --git a/tests/baselines/reference/awaitCallExpressionInSyncFunction.symbols b/tests/baselines/reference/awaitCallExpressionInSyncFunction.symbols new file mode 100644 index 00000000000..b41b6c2f67a --- /dev/null +++ b/tests/baselines/reference/awaitCallExpressionInSyncFunction.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/awaitCallExpressionInSyncFunction.ts === +function foo() { +>foo : Symbol(foo, Decl(awaitCallExpressionInSyncFunction.ts, 0, 0)) + + const foo = await(Promise.resolve(1)); +>foo : Symbol(foo, Decl(awaitCallExpressionInSyncFunction.ts, 1, 8)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) + + return foo; +>foo : Symbol(foo, Decl(awaitCallExpressionInSyncFunction.ts, 1, 8)) +} + diff --git a/tests/baselines/reference/awaitCallExpressionInSyncFunction.types b/tests/baselines/reference/awaitCallExpressionInSyncFunction.types new file mode 100644 index 00000000000..d3aeb8a7236 --- /dev/null +++ b/tests/baselines/reference/awaitCallExpressionInSyncFunction.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/awaitCallExpressionInSyncFunction.ts === +function foo() { +>foo : () => any + + const foo = await(Promise.resolve(1)); +>foo : any +>await(Promise.resolve(1)) : any +>await : any +>Promise.resolve(1) : Promise +>Promise.resolve : { (): Promise; (value: T | PromiseLike): Promise; } +>Promise : PromiseConstructor +>resolve : { (): Promise; (value: T | PromiseLike): Promise; } +>1 : 1 + + return foo; +>foo : any +} + diff --git a/tests/cases/compiler/awaitCallExpressionInSyncFunction.ts b/tests/cases/compiler/awaitCallExpressionInSyncFunction.ts new file mode 100644 index 00000000000..ac0a0f0b93f --- /dev/null +++ b/tests/cases/compiler/awaitCallExpressionInSyncFunction.ts @@ -0,0 +1,6 @@ +// @target: esnext + +function foo() { + const foo = await(Promise.resolve(1)); + return foo; +} diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction16.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction16.ts new file mode 100644 index 00000000000..1f7c963f9b0 --- /dev/null +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction16.ts @@ -0,0 +1,16 @@ +/// + +////function foo() { +//// const foo = await(Promise.resolve(1)); +//// return foo; +////} + +verify.codeFix({ + index: 0, + description: "Add async modifier to containing function", + newFileContent: +`async function foo() { + const foo = await(Promise.resolve(1)); + return foo; +}`, +});