From d7247770886c619263482c3e083bed9f97b22688 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Thu, 11 Nov 2021 19:17:17 +1300 Subject: [PATCH] fix(eslint-plugin): check optional chaining for floating promises (#4096) --- .../src/rules/no-floating-promises.ts | 8 +- .../tests/rules/no-floating-promises.test.ts | 80 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/no-floating-promises.ts b/packages/eslint-plugin/src/rules/no-floating-promises.ts index 5687f08a06b..edd26225323 100644 --- a/packages/eslint-plugin/src/rules/no-floating-promises.ts +++ b/packages/eslint-plugin/src/rules/no-floating-promises.ts @@ -65,7 +65,13 @@ export default util.createRule({ return; } - if (isUnhandledPromise(checker, node.expression)) { + let expression = node.expression; + + if (expression.type === AST_NODE_TYPES.ChainExpression) { + expression = expression.expression; + } + + if (isUnhandledPromise(checker, expression)) { if (options.ignoreVoid) { context.report({ node, diff --git a/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts b/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts index e7dfe710f15..e9a63df2b5d 100644 --- a/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts @@ -334,6 +334,28 @@ async function test() { returnsPromise()?.finally(() => {}); return returnsPromise(); } + `, + ` +const doSomething = async ( + obj1: { a?: { b?: { c?: () => Promise } } }, + obj2: { a?: { b?: { c: () => Promise } } }, + obj3: { a?: { b: { c?: () => Promise } } }, + obj4: { a: { b: { c?: () => Promise } } }, + obj5: { a?: () => { b?: { c?: () => Promise } } }, + obj6?: { a: { b: { c?: () => Promise } } }, + callback?: () => Promise, +): Promise => { + await obj1.a?.b?.c?.(); + await obj2.a?.b?.c(); + await obj3.a?.b.c?.(); + await obj4.a.b.c?.(); + await obj5.a?.().b?.c?.(); + await obj6?.a.b.c?.(); + + return callback?.(); +}; + +void doSomething(); `, // ignoreIIFE { @@ -414,6 +436,64 @@ async function test() { }, ], }, + { + code: ` +const doSomething = async ( + obj1: { a?: { b?: { c?: () => Promise } } }, + obj2: { a?: { b?: { c: () => Promise } } }, + obj3: { a?: { b: { c?: () => Promise } } }, + obj4: { a: { b: { c?: () => Promise } } }, + obj5: { a?: () => { b?: { c?: () => Promise } } }, + obj6?: { a: { b: { c?: () => Promise } } }, + callback?: () => Promise, +): Promise => { + obj1.a?.b?.c?.(); + obj2.a?.b?.c(); + obj3.a?.b.c?.(); + obj4.a.b.c?.(); + obj5.a?.().b?.c?.(); + obj6?.a.b.c?.(); + + callback?.(); +}; + +doSomething(); + `, + errors: [ + { + line: 11, + messageId: 'floatingVoid', + }, + { + line: 12, + messageId: 'floatingVoid', + }, + { + line: 13, + messageId: 'floatingVoid', + }, + { + line: 14, + messageId: 'floatingVoid', + }, + { + line: 15, + messageId: 'floatingVoid', + }, + { + line: 16, + messageId: 'floatingVoid', + }, + { + line: 18, + messageId: 'floatingVoid', + }, + { + line: 21, + messageId: 'floatingVoid', + }, + ], + }, { options: [{ ignoreVoid: true }], code: `