tsdoc icon indicating copy to clipboard operation
tsdoc copied to clipboard

eslint-plugin-tsdoc: allow policies to be ignored in tsdoc/syntax rule

Open bitjson opened this issue 4 years ago • 12 comments

Now that less-strict parsing for @param tags is merged (https://github.com/microsoft/tsdoc/issues/128), I'd love to be able to loosen the requirements of the tsdoc/syntax rule to allow for certain deviations from the expected syntax.

Primarily, VSCode's built-in JSDoc support automatically adds a doc comment where each @param tag is followed immediately by a description, without the expected hyphen. With the following .eslintrc configuration:

{
  rules: {
    'tsdoc/syntax': 'warn'
  }
}

This snippet is valid:

/**
 * Description
 * @param a - first number
 * @param b - second number
 */
const add = (a: number, b: number) => a + b;

While this snippet:

/**
 * Description
 * @param a first number
 * @param b second number
 */
const add = (a: number, b: number) => a + b;

Warns with the following:

tsdoc-param-tag-missing-hyphen: The @param block should be followed by a parameter name and then a hyphen eslint(tsdoc/syntax)

I'd love to be able to ignore this particular syntax deviation with something like:

{
  rules: {
    'tsdoc/syntax': ['warn', ignore: ['tsdoc-param-tag-missing-hyphen'] ]
  }
}

bitjson avatar Mar 03 '20 20:03 bitjson

This is a good idea. However I think we might want to approach it via the tsdoc.json config file rather than via ESLint's configuration. The reason is that you are not really suppressing a warning, but rather defining the kind of TSDoc parsing that you want for your source files. Putting the suppression in tsdoc.json will prevent other tools from reporting the same errors when they invoke the parser.

Long term, we intend to provide a "lax mode" as well as other compatibility settings for the TSDoc parser. But in the short term, this kind of problem can be solved pretty well by simply filtering out specific error IDs as you suggest. (The reason that's not a perfect solution is that the syntax highlighting may sometimes color the bad characters in red even though the error message is hidden.)

eslint-plugin-tsdoc already supports tsdoc.json, so we would simply need to improve tsdoc.schema.json to support something like this:

your-project/tsdoc.json

{
  "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
  "ignoreMessageIds": [
    "tsdoc-config-file-not-found"
  ]
}

...and then pass that setting through to the parser. It's mostly plumbing work, since in the end all we're doing is adding a filter to ParserMessageLog.addMessage().

octogonz avatar Mar 27 '20 01:03 octogonz

I just run into a problem and disabling rules doesn't work as usual where I have a section in the .eslintrc.json for *spec.ts files

https://jestjs.io/docs/en/configuration#testenvironment-string

/**
 * @jest-environment jsdom
 */
  2:4  warning  tsdoc-characters-after-block-tag: The token "@jest" looks like a TSDoc tag but contains an invalid character "-"; if it is not a tag, use a backslash to escape the "@"  tsdoc/syntax

but haven't found a way to disable this rule.

zoechi avatar Feb 25 '21 15:02 zoechi

I would second this request. Our use case is the need to disable the ts-doc-at-sign-in-word rule, The following should not trigger any warnings:

/**
 * A method description containing an [email protected] causing a linter warning.
 */
private getEmailAddress (): string {
    return '[email protected]';
}

countzero avatar Mar 18 '21 14:03 countzero

Yes, please an "ignoreMessageIds" is very much needed. Unless I am missing something it seems the eslint-plugin-tsdoc is all or nothing. Is there any way to stop reporting on some message ids at the moment?

rob4226 avatar Aug 23 '21 07:08 rob4226

Is there an update on this issue?

We are using a custom tag, "@author", which includes an email address.

Currently, it appears to be impossible to provide this address without triggering the linter.

hahanein avatar Sep 07 '22 10:09 hahanein

I'm having somewhat similiar problem with project using Emotion.

With the way things are, I need to put the following line to the top of every file where Emotion is used.

/** @jsxImportSource @emotion/react */

Which trigger the warning:

tsdoc-undefined-tag: The TSDoc tag "@jsxImportSource" is not defined in this configurationeslint[tsdoc/syntax](https://tsdoc.org/pages/packages/eslint-plugin-tsdoc)

I've followed the workaround from https://github.com/microsoft/tsdoc/issues/213#issuecomment-584750202 and added @jsxImportSource as custom tag in a tsdoc.json file:

{
  "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
  "tagDefinitions": [
    {
      "tagName": "@jsxImportSource",
      "syntaxKind": "modifier"
    }
  ],
  "supportForTags": {
    "@jsxImportSource": true
  }
}

It works, eslint-tsdoc recognizes @jsxImportSource as defined tag, but... it threw another warning

tsdoc-characters-after-block-tag: The token "@emotion" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@"eslint[tsdoc/syntax](https://tsdoc.org/pages/packages/eslint-plugin-tsdoc)

At this point, since I have no idea how to make my custom tsdoc tag @jsxImportSource from throwing tsdoc-characters-after-block-tag warning, I'm just exchanging one warning with another... :shrug:


FWIW,

The jsdoc/check-tag-names rule has jsxTags options for allowing tags used to control JSX output (jsx, jsxFrag, jsxImportSource, jsxRuntime)

Please, rather than going for all or nothing tsdoc/syntax rule, let user have some way to control the tsdoc/syntax validation. Off-loading the settings to tsdoc.json is one way, but defining an eslint custom rule with options/ exceptions, like the original proposed way above (and like all other eslint-plugin-* out there have done), IMO, is also a solution, e.g:

{
  rules: {
    'tsdoc/syntax': ['warn', { jsx: true, ignore: ['tsdoc-param-tag-missing-hyphen'] }]
  }
}

IronGeek avatar Nov 08 '22 13:11 IronGeek

So basically there is no way to keep using @author if we want to use eslint-plugin-tsdoc?

ssbarnea avatar Jan 03 '23 16:01 ssbarnea

re: https://github.com/microsoft/tsdoc/issues/220#issuecomment-1369968157

So basically there is no way to keep using @author if we want to use eslint-plugin-tsdoc?

of cause you could create own tags.

this is my tsdoc.json file:

{
  "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
  "tagDefinitions": [
    {
      "tagName": "@since",
      "syntaxKind": "block",
      "allowMultiple": false
    },
    {
      "tagName": "@author",
      "syntaxKind": "block",
      "allowMultiple": true
    },
    {
      "tagName": "@TODO",
      "syntaxKind": "block",
      "allowMultiple": true
    }
  ]
}

jkowalleck avatar Jan 29 '23 11:01 jkowalleck

This would be a great (and essential) addition. What is the status of this?

Patrick-clone avatar Mar 27 '23 13:03 Patrick-clone

on. What is the status of this?

I use tsdoc in combination with api-extractor. In api-extractor.json you can specify which error/warnings to suppress/ignore see: https://api-extractor.com/pages/configs/api-extractor_json/#messagestsdocmessagereporting

Patrick-clone avatar Mar 28 '23 07:03 Patrick-clone

For anyone who just needs this, allow me to present you with something beyond horrific.

npm install --save-dev eslint-plugin-local-rules

Create a file called `eslint-local-rules.cjs' next to your eslint config:

/**
 * Likely going to hell for this. TSDoc plugin does not allow configuring
 * additional tags so I check the error message for tags I want and nullify that
 * error.
 */

const plugin = require('eslint-plugin-tsdoc')

const originalRule = plugin.rules.syntax

const ALLOWED_TAGS = ['@category']

module.exports = {
  'tsdoc/syntax': {
    ...originalRule,

    create: (context) => {
      const hackedContext = {
        report: (opts) => {
          if (
            opts.messageId === 'tsdoc-undefined-tag' &&
            opts?.data?.unformattedText &&
            ALLOWED_TAGS.some(
              (tag) => opts.data.unformattedText.indexOf(tag) !== -1
            )
          ) {
            return
          }

          return context.report(opts)
        },
      }

      Object.setPrototypeOf(hackedContext, context)

      const originalCreateResult = originalRule.create(hackedContext)
      return originalCreateResult
    },
  },
}

In this example I make the @category tag allowed.

Now in your eslint config:

// ...

plugins: ['eslint-plugin-local-rules'] // add this

// ...

'local-rules/tsdoc/syntax': 'error',

May the Lord forgive me for my trespasses 😂

adamscybot avatar Jul 11 '23 01:07 adamscybot