From 650a176a84825bd70de1cdf93369a6ddfed89292 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Tue, 5 May 2020 01:27:22 +0000 Subject: [PATCH] Cherry-pick PR #36654 into release-3.9 Component commits: 766a201dec feat(36266): add a quick fix for incorrect return types in async functions 889e82b211 Make `getAwaitedType` private Also, fix an additional baseline change and break up huge line. --- src/compiler/checker.ts | 3 +- src/compiler/diagnosticMessages.json | 10 ++- src/compiler/types.ts | 2 + .../codefixes/fixReturnTypeInAsyncFunction.ts | 70 +++++++++++++++++++ src/services/tsconfig.json | 1 + .../asyncArrowFunction_allowJs.errors.txt | 8 +-- .../asyncFunctionDeclaration15_es6.errors.txt | 20 +++--- .../asyncImportedPromise_es6.errors.txt | 4 +- .../asyncQualifiedReturnType_es6.errors.txt | 4 +- .../codeFixReturnTypeInAsyncFunction1.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction10.ts | 13 ++++ .../codeFixReturnTypeInAsyncFunction11.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction12.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction13.ts | 13 ++++ .../codeFixReturnTypeInAsyncFunction14.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction15.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction16.ts | 15 ++++ .../codeFixReturnTypeInAsyncFunction17.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction2.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction3.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction4.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction5.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction6.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction7.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction8.ts | 10 +++ .../codeFixReturnTypeInAsyncFunction9.ts | 13 ++++ ...codeFixReturnTypeInAsyncFunction_fixAll.ts | 50 +++++++++++++ 27 files changed, 336 insertions(+), 20 deletions(-) create mode 100644 src/services/codefixes/fixReturnTypeInAsyncFunction.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts create mode 100644 tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bc999936e81c..eb11c372f8c09 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -406,6 +406,7 @@ namespace ts { }, getParameterType: getTypeAtPosition, getPromisedTypeOfPromise, + getAwaitedType: type => getAwaitedType(type), getReturnTypeOfSignature, isNullableType, getNullableType, @@ -30695,7 +30696,7 @@ namespace ts { if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. - error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); + error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0, typeToString(getAwaitedType(returnType) || voidType)); return; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 1df368c4286ba..4c58d32cb7479 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -215,7 +215,7 @@ "category": "Error", "code": 1063 }, - "The return type of an async function or method must be the global Promise type.": { + "The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise<{0}>'?": { "category": "Error", "code": 1064 }, @@ -5189,6 +5189,14 @@ "category": "Message", "code": 90035 }, + "Replace '{0}' with 'Promise<{1}>'": { + "category": "Message", + "code": 90036 + }, + "Fix all incorrect return type of an async functions": { + "category": "Message", + "code": 90037 + }, "Declare a private field named '{0}'.": { "category": "Message", "code": 90053 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 778f2bbbc1d4e..ec6b4415ba32a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3421,6 +3421,8 @@ namespace ts { getWidenedType(type: Type): Type; /* @internal */ getPromisedTypeOfPromise(promise: Type, errorNode?: Node): Type | undefined; + /* @internal */ + getAwaitedType(type: Type): Type | undefined; getReturnTypeOfSignature(signature: Signature): Type; /** * Gets the type of a parameter at a given position in a signature. diff --git a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts new file mode 100644 index 0000000000000..39e2c1900f3c7 --- /dev/null +++ b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts @@ -0,0 +1,70 @@ +/* @internal */ +namespace ts.codefix { + const fixId = "fixReturnTypeInAsyncFunction"; + const errorCodes = [ + Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0.code, + ]; + + interface Info { + readonly returnTypeNode: TypeNode; + readonly returnType: Type; + readonly promisedTypeNode: TypeNode; + readonly promisedType: Type; + } + + registerCodeFix({ + errorCodes, + fixIds: [fixId], + getCodeActions: context => { + const { sourceFile, program, span } = context; + const checker = program.getTypeChecker(); + const info = getInfo(sourceFile, program.getTypeChecker(), span.start); + if (!info) { + return undefined; + } + const { returnTypeNode, returnType, promisedTypeNode, promisedType } = info; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, returnTypeNode, promisedTypeNode)); + return [createCodeFixAction( + fixId, changes, + [Diagnostics.Replace_0_with_Promise_1, + checker.typeToString(returnType), checker.typeToString(promisedType)], + fixId, Diagnostics.Fix_all_incorrect_return_type_of_an_async_functions)]; + }, + getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { + const info = getInfo(diag.file, context.program.getTypeChecker(), diag.start); + if (info) { + doChange(changes, diag.file, info.returnTypeNode, info.promisedTypeNode); + } + }) + }); + + function getInfo(sourceFile: SourceFile, checker: TypeChecker, pos: number): Info | undefined { + const returnTypeNode = getReturnTypeNode(sourceFile, pos); + if (!returnTypeNode) { + return undefined; + } + + const returnType = checker.getTypeFromTypeNode(returnTypeNode); + const promisedType = checker.getAwaitedType(returnType) || checker.getVoidType(); + const promisedTypeNode = checker.typeToTypeNode(promisedType); + if (promisedTypeNode) { + return { returnTypeNode, returnType, promisedTypeNode, promisedType }; + } + } + + function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, returnTypeNode: TypeNode, promisedTypeNode: TypeNode): void { + changes.replaceNode(sourceFile, returnTypeNode, createTypeReferenceNode("Promise", [promisedTypeNode])); + } + + function getReturnTypeNode(sourceFile: SourceFile, pos: number): TypeNode | undefined { + if (isInJSFile(sourceFile)) { + return undefined; + } + + const token = getTokenAtPosition(sourceFile, pos); + const parent = findAncestor(token, isFunctionLikeDeclaration); + if (parent?.type) { + return parent.type; + } + } +} diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 117461bc1900c..bbe3956e173c1 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -85,6 +85,7 @@ "codefixes/fixMissingCallParentheses.ts", "codefixes/fixAwaitInSyncFunction.ts", "codefixes/inferFromUsage.ts", + "codefixes/fixReturnTypeInAsyncFunction.ts", "codefixes/disableJsDiagnostics.ts", "codefixes/helpers.ts", "codefixes/fixInvalidImportSyntax.ts", diff --git a/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt b/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt index e006f1668c13b..2a33da31b95d6 100644 --- a/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt +++ b/tests/baselines/reference/asyncArrowFunction_allowJs.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(3,17): error TS2322: Type '0' is not assignable to type 'string'. -tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(6,24): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(6,24): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(7,23): error TS2322: Type '0' is not assignable to type 'string'. -tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(10,24): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(10,24): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(12,2): error TS2322: Type '0' is not assignable to type 'string'. tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(19,3): error TS2345: Argument of type '() => Promise' is not assignable to parameter of type '() => string'. Type 'Promise' is not assignable to type 'string'. @@ -17,7 +17,7 @@ tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(19,3): error TS2 // Error (good) /** @type {function(): string} */ ~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? const b = async () => 0 ~ !!! error TS2322: Type '0' is not assignable to type 'string'. @@ -25,7 +25,7 @@ tests/cases/conformance/async/es2017/asyncArrowFunction/file.js(19,3): error TS2 // No error (bad) /** @type {function(): string} */ ~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? const c = async () => { return 0 ~~~~~~~~ diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt index 5ff67861350fd..5b054a616893a 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es6.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(6,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(6,23): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise<{}>'? tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(6,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. -tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(7,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(8,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(7,23): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(8,23): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(8,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. -tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(9,23): error TS1064: The return type of an async function or method must be the global Promise type. -tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(10,23): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(9,23): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? +tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(10,23): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member. tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration15_es6.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member. @@ -17,23 +17,23 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1 async function fn1() { } // valid: Promise async function fn2(): { } { } // error ~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise<{}>'? ~~~ !!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. async function fn3(): any { } // error ~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? async function fn4(): number { } // error ~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? ~~~~~~ !!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. async function fn5(): PromiseLike { } // error ~~~~~~~~~~~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? async function fn6(): Thenable { } // error ~~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? async function fn7() { return; } // valid: Promise async function fn8() { return 1; } // valid: Promise async function fn9() { return null; } // valid: Promise diff --git a/tests/baselines/reference/asyncImportedPromise_es6.errors.txt b/tests/baselines/reference/asyncImportedPromise_es6.errors.txt index 43b454826447c..402470313be51 100644 --- a/tests/baselines/reference/asyncImportedPromise_es6.errors.txt +++ b/tests/baselines/reference/asyncImportedPromise_es6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/async/es6/test.ts(3,25): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/test.ts(3,25): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? ==== tests/cases/conformance/async/es6/task.ts (0 errors) ==== @@ -9,5 +9,5 @@ tests/cases/conformance/async/es6/test.ts(3,25): error TS1064: The return type o class Test { async example(): Task { return; } ~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? } \ No newline at end of file diff --git a/tests/baselines/reference/asyncQualifiedReturnType_es6.errors.txt b/tests/baselines/reference/asyncQualifiedReturnType_es6.errors.txt index 205ea01673631..023579f6dcf51 100644 --- a/tests/baselines/reference/asyncQualifiedReturnType_es6.errors.txt +++ b/tests/baselines/reference/asyncQualifiedReturnType_es6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/async/es6/asyncQualifiedReturnType_es6.ts(6,21): error TS1064: The return type of an async function or method must be the global Promise type. +tests/cases/conformance/async/es6/asyncQualifiedReturnType_es6.ts(6,21): error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? ==== tests/cases/conformance/async/es6/asyncQualifiedReturnType_es6.ts (1 errors) ==== @@ -9,5 +9,5 @@ tests/cases/conformance/async/es6/asyncQualifiedReturnType_es6.ts(6,21): error T async function f(): X.MyPromise { ~~~~~~~~~~~~~~~~~ -!!! error TS1064: The return type of an async function or method must be the global Promise type. +!!! error TS1064: The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise'? } \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts new file mode 100644 index 0000000000000..9a52e24069045 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction1.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): number {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts new file mode 100644 index 0000000000000..0e7c399490477 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction10.ts @@ -0,0 +1,13 @@ +/// + +// @target: es2015 +////type Foo = "a" | "b"; +////async function fn(): Foo {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "Foo", "Foo"], + newFileContent: +`type Foo = "a" | "b"; +async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts new file mode 100644 index 0000000000000..338087032a208 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction11.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): PromiseLike {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "PromiseLike", "string"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts new file mode 100644 index 0000000000000..0e3cb2b90c635 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction12.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): PromiseLike {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "PromiseLike", "void"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts new file mode 100644 index 0000000000000..0cbc185957181 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction13.ts @@ -0,0 +1,13 @@ +/// + +// @target: es2015 +////declare class Thenable { then(): void; } +////async function fn(): Thenable {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "Thenable", "void"], + newFileContent: +`declare class Thenable { then(): void; } +async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts new file mode 100644 index 0000000000000..315c3ff5aeaf2 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction14.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): string | symbol {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "string | symbol", "string | symbol"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts new file mode 100644 index 0000000000000..ff0f610574883 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction15.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////const foo = async function (): number {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: `const foo = async function (): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts new file mode 100644 index 0000000000000..e0430490b5044 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction16.ts @@ -0,0 +1,15 @@ +/// + +// @target: es2015 +////class A { +//// async foo(): number {} +////} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: +`class A { + async foo(): Promise {} +}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts new file mode 100644 index 0000000000000..082d4ab2fe54f --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction17.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////const foo = async (): number => {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "number", "number"], + newFileContent: `const foo = async (): Promise => {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts new file mode 100644 index 0000000000000..10d07519e7dc8 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction2.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): boolean {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "boolean", "boolean"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts new file mode 100644 index 0000000000000..06eca5ee4fb83 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction3.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): string {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "string", "string"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts new file mode 100644 index 0000000000000..3aff287ed2c25 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction4.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): void {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "void", "void"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts new file mode 100644 index 0000000000000..dc3a781cacc82 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction5.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): null {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "null", "null"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts new file mode 100644 index 0000000000000..0d027d6a27845 --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction6.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): undefined {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "undefined", "undefined"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts new file mode 100644 index 0000000000000..4d9beac706b7c --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction7.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): any {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "any", "any"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts new file mode 100644 index 0000000000000..0533791f6f45e --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction8.ts @@ -0,0 +1,10 @@ +/// + +// @target: es2015 +////async function fn(): symbol {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "symbol", "symbol"], + newFileContent: `async function fn(): Promise {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts new file mode 100644 index 0000000000000..6614735af7d7f --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction9.ts @@ -0,0 +1,13 @@ +/// + +// @target: es2015 +////interface Foo {} +////async function fn(): Foo {} + +verify.codeFix({ + index: 0, + description: [ts.Diagnostics.Replace_0_with_Promise_1.message, "Foo", "Foo"], + newFileContent: +`interface Foo {} +async function fn(): Promise> {}` +}); diff --git a/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts new file mode 100644 index 0000000000000..4ad9a351364ed --- /dev/null +++ b/tests/cases/fourslash/codeFixReturnTypeInAsyncFunction_fixAll.ts @@ -0,0 +1,50 @@ +/// + +// @target: es2015 +////declare class Thenable { then(): void; } +////interface Foo {} +////type Bar = "a" | "b"; +//// +////async function f1(): number {} +////async function f2(): boolean {} +////async function f3(): string {} +////async function f4(): void {} +////async function f5(): null {} +////async function f6(): undefined {} +////async function f7(): any {} +////async function f8(): symbol {} +//// +////async function f9(): Foo {} +////async function f10(): Bar {} +////async function f11(): PromiseLike {} +////async function f12(): PromiseLike {} +////async function f13(): Thenable {} +//// +////async function f14(): string | symbol {} + + +verify.codeFixAll({ + fixId: "fixReturnTypeInAsyncFunction", + fixAllDescription: ts.Diagnostics.Fix_all_incorrect_return_type_of_an_async_functions.message, + newFileContent: +`declare class Thenable { then(): void; } +interface Foo {} +type Bar = "a" | "b"; + +async function f1(): Promise {} +async function f2(): Promise {} +async function f3(): Promise {} +async function f4(): Promise {} +async function f5(): Promise {} +async function f6(): Promise {} +async function f7(): Promise {} +async function f8(): Promise {} + +async function f9(): Promise> {} +async function f10(): Promise {} +async function f11(): Promise {} +async function f12(): Promise {} +async function f13(): Promise {} + +async function f14(): Promise {}` +});