Add prefer-options-object-param rule and tune max-params - #28
Merged
Merged
Conversation
…text param removeListMember took 5 required parameters, tripping this repo's own max-params threshold. fixer and sourceCode were always passed together at every call site, so grouping them into one FixerContext parameter is a genuine reduction, not a workaround.
The first-token mirror of the existing lastTokenOrThrow, for the identical reason: getFirstToken only ever returns null for a node with genuinely no tokens at all, never true of a real AST node this codebase's own rules call it on.
Detects a run of 2+ trailing optional parameters ('?'-marked or
default-valued) and suggests bundling them into a single destructured
'options' parameter. Without this, a caller needing only the last
optional parameter must still pass 'undefined' for every optional
parameter before it.
Uses hasSuggestions rather than a silent fixable autofix, since the
fix rewrites both a parameter list and the function body. Every
type-text extraction is a verbatim source-text slice rather than a
checker-based reconstruction, so the rule needs no type information
at all despite living in the type-checked bundle.
Reports but withholds the suggestion whenever collapsing the run
would not be safe or mechanical: a parameter property, a parameter
with no simple resolvable name and explicit type of its own, a
decorated parameter, a rest parameter anywhere in the parameter list,
no block body at all (an arrow's expression body or any
declaration-only signature), a '@PARAM' JSDoc tag naming a parameter
in the run, or a parameter/local variable already named 'options'.
Registers exadev/prefer-options-object-param in the type-checked
bundle only, alongside prefer-readonly-object-param and
prefer-numeric-sort-compare, for a consistent "every rewrite-
suggestion prefer-* rule lives here" story even though it needs no
type information itself.
Adds core max-params at { max: 4 }, one above its own default, to
both plugin.configs.recommended and the type-checked bundle. It is a
deliberately loose backstop against excessive REQUIRED parameters, a
shape prefer-options-object-param is structurally blind to since it
only ever looks at trailing OPTIONAL parameters.
Documents both in the README.
Mearman
marked this pull request as ready for review
September 19, 2026 09:55
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
🎉 This PR is included in version 2.20.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new custom rule,
exadev/prefer-options-object-param, that detects a run of 2+ trailing optional parameters and suggests bundling them into a single destructuredoptionsparameter — the motivating case is a constructor/function where a caller needing only the last optional parameter has to passundefinedfor every one before it.Also tunes core
max-paramsto{ max: 4 }(one above its own default) in both bundles, as a deliberately loose backstop against a genuinely excessive number of required parameters — a shape the new rule is structurally blind to, since it only looks at the trailing optional run.Changes
exadev/prefer-options-object-param: type-aware in placement only (see the rule's own file header) — every check and every fix is purely syntactic, using verbatim source-text slices rather than checker-based type reconstruction. UseshasSuggestions, not a silentfixable, since the fix rewrites both a parameter list and the function body. Registered only in the type-checked bundle, alongsideprefer-readonly-object-param/prefer-numeric-sort-compare.max-paramsat{ max: 4 }, registered in bothplugin.configs.recommendedand the type-checked bundle (needs no type info).no-non-barrel-reexport.ts:removeListMemberhad 5 required parameters, tripping the newly-enabledmax-params. Bundled its always-togetherfixer/sourceCodepair into oneFixerContextparameter — a genuine reduction, not a workaround.ts-node-guards.ts: addedfirstTokenOrThrow, the first-token mirror of the existinglastTokenOrThrow, used by the new rule's fixer.Test plan
pnpm test— full suite green (805 tests), including 33 new tests for the rule covering every valid/invalid case and every bail-out named in the design (parameter property, missing name/type, decorated parameter, rest parameter anywhere in the list, no block body — arrow expression body / declaration-only signatures /.d.ts,@paramJSDoc mention,options-name collision), plus the realWireMeshTransportconstructor shape as a permanent regression case.pnpm typecheck— clean.pnpm lint— clean.pnpm build— clean.dist/) run through a realLinter, against the exactWireMeshTransportconstructor shape: the rule reports and the suggested fix's output was confirmed againsttsc --strict— the newoptions-based call site typechecks cleanly, and the old stale positional call site fails with a realTS2554"Expected 2-3 arguments, but got 10" error.