From b8e5d46d2a0113b3504024341e15a3aeebbb6a89 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Tue, 24 Sep 2024 01:02:40 +0900 Subject: [PATCH 1/4] fix(eslint-plugin): [no-misused-promises] check contextual type --- .../src/rules/no-misused-promises.ts | 14 +++++ .../tests/rules/no-misused-promises.test.ts | 63 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index 9edd31141e0a..fa598f6fa1de 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -826,6 +826,20 @@ function voidFunctionArguments( thenableReturnIndices, voidReturnIndices, ); + const contextualType = checker.getContextualTypeForArgumentAtIndex( + node, + index, + ); + if (contextualType !== type) { + checkThenableOrVoidArgument( + checker, + node, + contextualType, + index, + thenableReturnIndices, + voidReturnIndices, + ); + } } } } 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 0c6b33582825..3434ffd39249 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts @@ -1051,6 +1051,21 @@ interface MyInterface extends MyCall, MyIndex, MyConstruct, MyMethods { const array: number[] = [1, 2, 3]; array.filter(a => a > 1); `, + ` +type ReturnsPromiseVoid = () => Promise; +declare const useCallback: unknown>( + fn: T, +) => T; +useCallback(async () => {}); + `, + ` +type ReturnsVoid = () => void; +type ReturnsPromiseVoid = () => Promise; +declare const useCallback: unknown>( + fn: T, +) => T; +useCallback(async () => {}); + `, ], invalid: [ @@ -2322,5 +2337,53 @@ tuple.find(() => Promise.resolve(false)); }, ], }, + { + code: ` +type ReturnsVoid = () => void; +declare const useCallback: unknown>( + fn: T, +) => T; +declare const useCallbackReturningVoid: typeof useCallback; +useCallbackReturningVoid(async () => {}); // correct + `, + errors: [ + { + line: 7, + messageId: 'voidReturnArgument', + }, + ], + }, + { + code: ` +type ReturnsVoid = () => void; +declare const useCallback: unknown>( + fn: T, +) => T; +useCallback(async () => {}); + `, + errors: [ + { + line: 6, + messageId: 'voidReturnArgument', + }, + ], + }, + { + code: ` +interface Foo { + (callback: () => T): void; + (callback: () => number): void; +} +declare const foo: Foo; + +foo(async () => {}); + `, + errors: [ + { + line: 6, + messageId: 'voidReturnArgument', + }, + ], + }, ], }); From 05534ceed6a1f96a2c22316ae152ee690177798f Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Tue, 24 Sep 2024 01:25:38 +0900 Subject: [PATCH 2/4] fix --- packages/eslint-plugin/tests/rules/no-misused-promises.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3434ffd39249..9c9c138458aa 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts @@ -2380,7 +2380,7 @@ foo(async () => {}); `, errors: [ { - line: 6, + line: 8, messageId: 'voidReturnArgument', }, ], From 707d78705f00b8b95833264fdb9b1e40debc4996 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Wed, 25 Sep 2024 23:08:10 +0900 Subject: [PATCH 3/4] apply review --- .../src/rules/no-misused-promises.ts | 28 ++++++------ .../tests/rules/no-misused-promises.test.ts | 44 +++++++++++++++++++ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index fa598f6fa1de..dd219fa95d3f 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -743,6 +743,20 @@ function checkThenableOrVoidArgument( ) { voidReturnIndices.add(index); } + const contextualType = checker.getContextualTypeForArgumentAtIndex( + node, + index, + ); + if (contextualType !== type) { + checkThenableOrVoidArgument( + checker, + node, + contextualType, + index, + thenableReturnIndices, + voidReturnIndices, + ); + } } // Get the positions of arguments which are void functions (and not also @@ -826,20 +840,6 @@ function voidFunctionArguments( thenableReturnIndices, voidReturnIndices, ); - const contextualType = checker.getContextualTypeForArgumentAtIndex( - node, - index, - ); - if (contextualType !== type) { - checkThenableOrVoidArgument( - checker, - node, - contextualType, - index, - thenableReturnIndices, - voidReturnIndices, - ); - } } } } 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 9c9c138458aa..ae85d6b15c37 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts @@ -2385,5 +2385,49 @@ foo(async () => {}); }, ], }, + { + code: ` +declare function tupleFn unknown>( + ...fns: [T, string, T] +): void; +tupleFn<() => void>( + async () => {}, + 'foo', + async () => {}, +); + `, + errors: [ + { + line: 6, + messageId: 'voidReturnArgument', + }, + { + line: 8, + messageId: 'voidReturnArgument', + }, + ], + }, + { + code: ` +declare function arrayFn unknown>( + ...fns: (T | string)[] +): void; +arrayFn<() => void>( + async () => {}, + 'foo', + async () => {}, +); + `, + errors: [ + { + line: 6, + messageId: 'voidReturnArgument', + }, + { + line: 8, + messageId: 'voidReturnArgument', + }, + ], + }, ], }); From 107a1250d763ea84aa6ca468467da6a552a5ac82 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Wed, 25 Sep 2024 23:09:34 +0900 Subject: [PATCH 4/4] remove comment --- packages/eslint-plugin/tests/rules/no-misused-promises.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ae85d6b15c37..0f4330f890ca 100644 --- a/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-misused-promises.test.ts @@ -2344,7 +2344,7 @@ declare const useCallback: unknown>( fn: T, ) => T; declare const useCallbackReturningVoid: typeof useCallback; -useCallbackReturningVoid(async () => {}); // correct +useCallbackReturningVoid(async () => {}); `, errors: [ { 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