Repository navigation
JSDoc: settle how we document destructured component props #34
Description
In #18, @joedolson flagged src/settings/index.tsx:94:
I'm not a big fan of using unnamed parameters, but I think that's not a blocker for accepting this PR, since the purpose of the PR is to address linting issues without changing the code.
Agreed it wasn't in scope there. Filing it so we can settle the pattern, since it'll recur in every TSX component we document.
What it refers to
/**
* A single badge. Only rendered when the module is genuinely in that
* state — "Stable" is the default and never gets a chip.
* @param root0
* @param root0.kind
* @param root0.label
*/
function Badge( { kind, label }: { … } ): JSX.Element {root0 is eslint-plugin-jsdoc's placeholder for a destructured parameter with no name — generated by the jsdoc/require-param autofix.
The awkward part
In @wordpress/eslint-plugin's config:
jsdoc/require-jsdoc→ off (docblocks optional)jsdoc/require-param→ error (but if you write one, every param must be tagged)jsdoc/require-param-description→ off (tags need no description)
So writing a helpful prose docblock forces bare @param root0.kind tags that convey nothing, while leaving the component undocumented stays clean. ModuleBadges (index.tsx:114) and IssueRow (sidebar.tsx:18) destructure props exactly the same way and have no tags — only because neither has a docblock. The rule effectively penalizes documenting.
Worth knowing: upstream Gutenberg has ~74 @param root0 tags, so the name itself is tolerated there — but theirs carry real descriptions (@param root0.src Image source URL.). Ours have none, so we get the ugly name and no information.
Scope
9 tags, 2 functions, 1 file: Badge (src/settings/index.tsx:98) and ModuleRow (:152). Small today — the question is what we do going forward.
Options
A — Name the parameter. Take props and destructure in the body:
function Badge( props: BadgeProps ): JSX.Element {
const { kind, label } = props;Gives a single @param props tag and directly answers the objection. Costs one line per component.
B — Keep root0, require descriptions. Match Gutenberg: turn on jsdoc/require-param-description so the tags at least earn their place. Doesn't fix the naming.
C — Disable the jsdoc param rules for .ts/.tsx. The TypeScript annotations already give every param a name and type; @param root0.kind is strictly redundant with kind: 'experiment' | 'core-track'. Lets docblocks carry prose only, which is the part that actually helps.
Suggestion
C, possibly with A where a named props type reads better anyway. In a TypeScript codebase the param tags duplicate the type signature, and removing the requirement means documenting a component no longer costs you a block of noise.
Whichever we pick belongs in CONTRIBUTING.md alongside the PHP docblock standards, which are already documented in detail.
Activity
aduth commentedon Sep 29, 2026
There's precedent for this in Gutenberg, for what it's worth. It's rather coarse though, assuming that
.tsxfiles primarily contain a single component function whose params are self-evident by nature of it being a React component.The documentation should be expected to come through from the associated TypeScript types, which themselves should have JSDoc annotations on each of their interface prop members.