From b4a53f74a6bf51f6d2bed3b18f60283f3edad914 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Fri, 14 Mar 2025 16:12:54 +0200 Subject: [PATCH 1/8] initial implementation --- .../src/rules/promise-function-async.ts | 16 ++++++++++++++-- .../tests/rules/promise-function-async.test.ts | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 06fdd024c0e9..10a39ff0aafb 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -23,7 +23,7 @@ export type Options = [ checkMethodDeclarations?: boolean; }, ]; -export type MessageIds = 'missingAsync'; +export type MessageIds = 'missingAsync' | 'missingAsyncHybridReturn'; export default createRule({ name: 'promise-function-async', @@ -37,6 +37,8 @@ export default createRule({ fixable: 'code', messages: { missingAsync: 'Functions that return promises must be async.', + missingAsyncHybridReturn: + 'Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return both a promise and a non-promise.', }, schema: [ { @@ -164,10 +166,20 @@ export default createRule({ ), ) ) { + const isHybridReturnType = returnTypes.some( + type => + type.isUnion() && + !type.types.every(part => + containsAllTypesByName(part, true, allAllowedPromiseNames), + ), + ); + context.report({ loc: getFunctionHeadLoc(node, context.sourceCode), node, - messageId: 'missingAsync', + messageId: isHybridReturnType + ? 'missingAsyncHybridReturn' + : 'missingAsync', fix: fixer => { if ( node.parent.type === AST_NODE_TYPES.MethodDefinition || diff --git a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts index 5ab4887334dc..92f3dddc2d36 100644 --- a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts +++ b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts @@ -825,7 +825,7 @@ function promiseInUnionWithoutExplicitReturnType(p: boolean) { `, errors: [ { - messageId, + messageId: 'missingAsyncMixedReturn', }, ], output: ` From 9f2900ccd87c54ea914379bb74271ca21ccfe669 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Fri, 14 Mar 2025 16:13:25 +0200 Subject: [PATCH 2/8] tests --- .../rules/promise-function-async.test.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts index 92f3dddc2d36..0c90c3eab0a7 100644 --- a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts +++ b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts @@ -825,7 +825,7 @@ function promiseInUnionWithoutExplicitReturnType(p: boolean) { `, errors: [ { - messageId: 'missingAsyncMixedReturn', + messageId: 'missingAsyncHybridReturn', }, ], output: ` @@ -836,6 +836,36 @@ async function promiseInUnionWithoutExplicitReturnType(p: boolean) { }, { code: ` +class PromiseType { + s?: string; +} + +function promiseInUnionWithoutExplicitReturnType(p: boolean) { + return p ? new PromiseType() : 5; +} + `, + errors: [ + { + messageId: 'missingAsyncHybridReturn', + }, + ], + options: [ + { + allowedPromiseNames: ['PromiseType'], + }, + ], + output: ` +class PromiseType { + s?: string; +} + +async function promiseInUnionWithoutExplicitReturnType(p: boolean) { + return p ? new PromiseType() : 5; +} + `, + }, + { + code: ` function overloadingThatCanReturnPromise(): Promise; function overloadingThatCanReturnPromise(a: boolean): Promise; function overloadingThatCanReturnPromise( From db52ca5b26505452b772acf8aa6f0882c7e07f81 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Fri, 14 Mar 2025 16:17:18 +0200 Subject: [PATCH 3/8] snapshots --- .../docs-eslint-output-snapshots/promise-function-async.shot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot index 0c91850303e9..cb6bd99f2ea8 100644 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot +++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot @@ -12,7 +12,7 @@ function functionReturnsPromise() { } function functionReturnsUnionWithPromiseImplicitly(p: boolean) { -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions that return promises must be async. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return both a promise and a non-promise. return p ? 'value' : Promise.resolve('value'); } " From 8b51b8dd97a2d56fcc24da100c9f8ac191c280da Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Fri, 14 Mar 2025 16:37:08 +0200 Subject: [PATCH 4/8] cover overloading case --- .../rules/promise-function-async.test.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts index 0c90c3eab0a7..da1999e93e82 100644 --- a/packages/eslint-plugin/tests/rules/promise-function-async.test.ts +++ b/packages/eslint-plugin/tests/rules/promise-function-async.test.ts @@ -836,6 +836,35 @@ async function promiseInUnionWithoutExplicitReturnType(p: boolean) { }, { code: ` +function test1(): 'one' | Promise<'one'>; +function test1(a: number): Promise; +function test1(a?: number) { + if (a) { + return Promise.resolve(a); + } + + return Math.random() > 0.5 ? 'one' : Promise.resolve('one'); +} + `, + errors: [ + { + messageId: 'missingAsyncHybridReturn', + }, + ], + output: ` +function test1(): 'one' | Promise<'one'>; +function test1(a: number): Promise; +async function test1(a?: number) { + if (a) { + return Promise.resolve(a); + } + + return Math.random() > 0.5 ? 'one' : Promise.resolve('one'); +} + `, + }, + { + code: ` class PromiseType { s?: string; } From 9eb0f5b6e84a36c5eb97c476e419af48da484c06 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 18 Mar 2025 19:55:27 +0200 Subject: [PATCH 5/8] Update packages/eslint-plugin/src/rules/promise-function-async.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Josh Goldberg ✨ --- packages/eslint-plugin/src/rules/promise-function-async.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 10a39ff0aafb..372475f1b643 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -38,7 +38,7 @@ export default createRule({ messages: { missingAsync: 'Functions that return promises must be async.', missingAsyncHybridReturn: - 'Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return both a promise and a non-promise.', + 'Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return either a promise or a non-promise.', }, schema: [ { From 577b247218ec3b962d24f1fd5c6c0c57d3ab9be2 Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 18 Mar 2025 21:14:36 +0200 Subject: [PATCH 6/8] snapshots --- .../docs-eslint-output-snapshots/promise-function-async.shot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot index cb6bd99f2ea8..70b324735fcd 100644 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot +++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot @@ -12,7 +12,7 @@ function functionReturnsPromise() { } function functionReturnsUnionWithPromiseImplicitly(p: boolean) { -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return both a promise and a non-promise. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return either a promise or a non-promise. return p ? 'value' : Promise.resolve('value'); } " From f5b6f7593eedaaa2dc0ecd4d39bf55eb0ea9e18e Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 1 Apr 2025 18:50:44 +0300 Subject: [PATCH 7/8] Update packages/eslint-plugin/src/rules/promise-function-async.ts Co-authored-by: Kirk Waiblinger <53019676+kirkwaiblinger@users.noreply.github.com> --- packages/eslint-plugin/src/rules/promise-function-async.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 372475f1b643..1739e1508937 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -38,7 +38,7 @@ export default createRule({ messages: { missingAsync: 'Functions that return promises must be async.', missingAsyncHybridReturn: - 'Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return either a promise or a non-promise.', + 'Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return a union of promise and non-promise types.', }, schema: [ { From 6831cbfb872ca787b0dfa02f7654ff14bec4a60a Mon Sep 17 00:00:00 2001 From: Ronen Amiel Date: Tue, 1 Apr 2025 19:20:10 +0300 Subject: [PATCH 8/8] snapshots --- .../docs-eslint-output-snapshots/promise-function-async.shot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot index 70b324735fcd..e85a8bf8c387 100644 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot +++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/promise-function-async.shot @@ -12,7 +12,7 @@ function functionReturnsPromise() { } function functionReturnsUnionWithPromiseImplicitly(p: boolean) { -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return either a promise or a non-promise. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions that return promises must be async. Consider adding an explicit return type annotation if the function is intended to return a union of promise and non-promise types. return p ? 'value' : Promise.resolve('value'); } " pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy