diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index 15bf0c501d1..07fe430c175 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -312,6 +312,9 @@ export default util.createRule({ return; } + if (!returnsThenable(checker, tsNode)) { + return; + } const objType = checker.getContextualType(obj); if (objType === undefined) { return; @@ -329,10 +332,7 @@ export default util.createRule({ tsNode.name, ); - if ( - isVoidReturningFunctionType(checker, tsNode.name, contextualType) && - returnsThenable(checker, tsNode) - ) { + if (isVoidReturningFunctionType(checker, tsNode.name, contextualType)) { context.report({ messageId: 'voidReturnProperty', node: node.value, @@ -378,8 +378,7 @@ export default util.createRule({ const contextualType = checker.getContextualType(value); if ( contextualType !== undefined && - isVoidReturningFunctionType(checker, value, contextualType) && - returnsThenable(checker, value.expression) + isVoidReturningFunctionType(checker, value, contextualType) ) { context.report({ messageId: 'voidReturnAttribute', diff --git a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts index c962761717d..025abd43f6e 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts @@ -427,6 +427,39 @@ function restTuple(..._args: string[]): void {} restTuple(); restTuple('Hello'); `, + ` + let value: Record void>; + value.sync = () => {}; + `, + ` + type ReturnsRecord = () => Record void>; + + const test: ReturnsRecord = () => { + return { sync: () => {} }; + }; + `, + ` + type ReturnsRecord = () => Record void>; + + function sync() {} + + const test: ReturnsRecord = () => { + return { sync }; + }; + `, + ` + function withTextRecurser( + recurser: (text: Text) => void, + ): (text: Text) => void { + return (text: Text): void => { + if (text.length) { + return; + } + + return recurser(node); + }; + } + `, ], invalid: [ @@ -1118,5 +1151,34 @@ restTuple(true, () => Promise.resolve(1)); `, errors: [{ line: 7, messageId: 'voidReturnArgument' }], }, + { + code: ` +type ReturnsRecord = () => Record void>; + +const test: ReturnsRecord = () => { + return { asynchronous: async () => {} }; +}; + `, + errors: [{ line: 5, messageId: 'voidReturnProperty' }], + }, + { + code: ` +let value: Record void>; +value.asynchronous = async () => {}; + `, + errors: [{ line: 3, messageId: 'voidReturnVariable' }], + }, + { + code: ` +type ReturnsRecord = () => Record void>; + +async function asynchronous() {} + +const test: ReturnsRecord = () => { + return { asynchronous }; +}; + `, + errors: [{ line: 7, messageId: 'voidReturnProperty' }], + }, ], });