Eslint-plugin-jsdoc: require-param reports false negative since v17.0.1

Created on 3 Dec 2019  路  9Comments  路  Source: gajus/eslint-plugin-jsdoc

Decided to update from v15 to v18 and one of the rules started acting up, so I tried a few different versions and found that v17.0.1 is the culprit.

The following piece of code used to pass the require-param check:

     * @param args Arguments compiled and provided by <redacted>.
     * @param args.options The options as provided by the user, or an empty object if not provided.
     * @param defaultOptions The default options as provided by the plugin, or an empty object.
     */
    public constructor({options, client}: {
        options: O;
        client: Redacted;
    }, defaultOptions: D) {
        this.client = client;
        this.options = merge(defaultOptions, options) as O & D;
        this.logger = signale.scope(`plugin:${this.constructor.name.replace(/redacted/gui, '').toLowerCase()}`);
    }

But now, it complains: Missing JSDoc @param "defaultOptions" declaration.
The automatic fixer wasn't of much help 馃槄 :

     * @param args Arguments compiled and provided by DullahanClient.
     * @param args.options The options as provided by the user, or an empty object if not provided.
     * @param defaultOptions The default options as provided by the plugin, or an empty object.
     * @param defaultOptions
     * @param defaultOptions
     * @param defaultOptions
     * @param defaultOptions
     * @param defaultOptions
     * @param defaultOptions
bug released

All 9 comments

I have added the following code to our testing framework and found no issues reported:

    {
      code: `
      class Quux {
        /**
         * @param args Arguments compiled and provided by <redacted>.
         * @param args.options The options as provided by the user, or an empty object if not provided.
         * @param defaultOptions The default options as provided by the plugin, or an empty object.
         */
        public constructor({options, client}: {
            options: O;
            client: Redacted;
        }, defaultOptions: D) {
            this.client = client;
            this.options = merge(defaultOptions, options) as O & D;
            this.logger = signale.scope(\`plugin:\${this.constructor.name.replace(/redacted/gui, '').toLowerCase()}\`);
        }
      }
      `,
      parser: require.resolve('@typescript-eslint/parser'),
    },

Weird, I do get issues. Maybe it's triggered because of another part of the documentation block?

I've stripped the file from a lot of content (and replaced all words I cannot share in public with my own name) and created a gist: https://gist.github.com/StephanBijzitter/6cee238bf73042ca37666ed2b5384df1

Running ESLint against this file now gives me the following errors:

v18.4.1, v17.0.1 (1 jsdoc error)

   3:5   error  Missing JSDoc @param "defaultOptions" declaration  jsdoc/require-param
  36:5   error  Useless constructor                                no-useless-constructor
  36:25  error  'options' is defined but never used                @typescript-eslint/no-unused-vars
  36:34  error  'client' is defined but never used                 @typescript-eslint/no-unused-vars
  39:8   error  'defaultOptions' is defined but never used         @typescript-eslint/no-unused-vars
  39:27  error  Unexpected empty constructor                       no-empty-function

v17.0.0 (0 jsdoc error)

  36:5   error  Useless constructor                         no-useless-constructor
  36:25  error  'options' is defined but never used         @typescript-eslint/no-unused-vars
  36:34  error  'client' is defined but never used          @typescript-eslint/no-unused-vars
  39:8   error  'defaultOptions' is defined but never used  @typescript-eslint/no-unused-vars
  39:27  error  Unexpected empty constructor                no-empty-function

Ah yes, 17.0.1 added an update from comment-parser which avoided treating ampersand-prefixed items within @example (like decorators) as being actual new jsdoc tags, so it makes sense the issue has an @example.

Am in the middle of something now, but you might test on runkit to see how comment-parser is currently parsing your code: https://npm.runkit.com/comment-parser . Will try to take a look later.

Cool, I haven't used comment-parser before (or runkit, that's quite awesome)!

I see tag: param, name: defaultOptions in the output and it also has the description and whether it's optional or not. So as far as I can tell, that works

We should look into why comment-parser is not handling this properly, but as a workaround (and what I'm guessing you wanted to do anyways), change this line:

*```typescript

to add a space after the asterisk, i.e., to this:
````

  • ```typescript
    ````

Then comment-parser properly parses, and we treat it as valid.

The comment-parser has been merged, and so we are just awaiting an npm release to update. But again, the workaround is available now if you like.

:tada: This issue has been resolved in version 18.4.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

This should now be fully fixed without need for the workaround. Thanks for the report and info!

@brettz9 Tested 18.4.2 with the workaround*, works.
Tested 18.4.3 without the workaround, works.

  • = You're right, I didn't even notice there was no space between the star and backtick in that location! I added the space and left it in there, it looks cleaner anyway.

Thanks for this really quick fix!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Fiyin-Anne picture Fiyin-Anne  路  4Comments

michaelfarrell76 picture michaelfarrell76  路  4Comments

hipstersmoothie picture hipstersmoothie  路  3Comments

zhaparoff picture zhaparoff  路  3Comments

tdmalone picture tdmalone  路  5Comments