From c5340140e836823f987a9252f8c6dfecaec82e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Jas=CC=8Cko?= Date: Wed, 17 Dec 2025 11:53:52 +0100 Subject: [PATCH] Support curried HOCs in customHOCs option Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jaskp <35872026+jaskp@users.noreply.github.com> --- src/only-export-components.test.ts | 15 +++++++++++++++ src/only-export-components.ts | 17 ++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/only-export-components.test.ts b/src/only-export-components.test.ts index 166e1c1..c80da2d 100755 --- a/src/only-export-components.test.ts +++ b/src/only-export-components.test.ts @@ -201,6 +201,21 @@ const valid = [ code: "const MyComponent = () => {}; export default observer(MyComponent);", options: [{ customHOCs: ["observer"] }], }, + { + name: "Curried HOC with styled (object form)", + code: "export const Flex = styled('div')({display: 'flex'});", + options: [{ customHOCs: ["styled"] }], + }, + { + name: "Curried HOC with styled (template literal form)", + code: "export const Flex = styled('div')`display: flex;`;", + options: [{ customHOCs: ["styled"] }], + }, + { + name: "Curried HOC only first call", + code: "export const Flex = styled('div');", + options: [{ customHOCs: ["styled"] }], + }, { name: "Local constant with component casing and non component function", code: "const SomeConstant = 42; export function someUtility() { return SomeConstant }", diff --git a/src/only-export-components.ts b/src/only-export-components.ts index 5ddcce5..d5474da 100644 --- a/src/only-export-components.ts +++ b/src/only-export-components.ts @@ -82,11 +82,18 @@ export const onlyExportComponents: TSESLint.RuleModule< if (!init) return false; const jsInit = skipTSWrapper(init); if (jsInit.type === "ArrowFunctionExpression") return true; - if ( - jsInit.type === "CallExpression" - && jsInit.callee.type === "Identifier" - ) { - return reactHOCs.includes(jsInit.callee.name); + if (jsInit.type === "CallExpression") { + // memo(...) + if (jsInit.callee.type === "Identifier") { + return reactHOCs.includes(jsInit.callee.name); + } + // Curried HOC: styled('div')({...}) + if ( + jsInit.callee.type === "CallExpression" + && jsInit.callee.callee.type === "Identifier" + ) { + return reactHOCs.includes(jsInit.callee.callee.name); + } } return false; };