eslint-plugin-jsdoc
JSDoc linting rules for ESLint.
Last updated a year ago by gajus .
BSD-3-Clause · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install eslint-plugin-jsdoc 
SYNC missed versions from official npm registry.

eslint-plugin-jsdoc

GitSpo Mentions NPM version Travis build status js-canonical-style

JSDoc linting rules for ESLint.

Installation

Install ESLint either locally or globally.

npm install --save-dev eslint

If you have installed ESLint globally, you have to install JSDoc plugin globally too. Otherwise, install it locally.

npm install --save-dev eslint-plugin-jsdoc

Configuration

Add plugins section to .eslintrc.* and specify eslint-plugin-jsdoc as a plugin.

{
    "plugins": [
        "jsdoc"
    ]
}

Finally, enable all of the rules that you would like to use.

{
    "rules": {
        "jsdoc/check-alignment": 1, // Recommended
        "jsdoc/check-examples": 1,
        "jsdoc/check-indentation": 1,
        "jsdoc/check-param-names": 1, // Recommended
        "jsdoc/check-syntax": 1,
        "jsdoc/check-tag-names": 1, // Recommended
        "jsdoc/check-types": 1, // Recommended
        "jsdoc/implements-on-classes": 1, // Recommended
        "jsdoc/match-description": 1,
        "jsdoc/newline-after-description": 1, // Recommended
        "jsdoc/no-types": 1,
        "jsdoc/no-undefined-types": 1, // Recommended
        "jsdoc/require-description": 1,
        "jsdoc/require-description-complete-sentence": 1,
        "jsdoc/require-example": 1,
        "jsdoc/require-hyphen-before-param-description": 1,
        "jsdoc/require-jsdoc": 1, // Recommended
        "jsdoc/require-param": 1, // Recommended
        "jsdoc/require-param-description": 1, // Recommended
        "jsdoc/require-param-name": 1, // Recommended
        "jsdoc/require-param-type": 1, // Recommended
        "jsdoc/require-returns": 1, // Recommended
        "jsdoc/require-returns-check": 1, // Recommended
        "jsdoc/require-returns-description": 1, // Recommended
        "jsdoc/require-returns-type": 1, // Recommended
        "jsdoc/valid-types": 1 // Recommended
    }
}

Or you can simply add the following to .eslintrc.*, which enables the rules commented above as "recommended":

{
  "extends": ["plugin:jsdoc/recommended"]
}

You can then selectively add to or override the recommended rules.

Options

Rules may, as per the ESLint user guide, have their own individual options. In eslint-plugin-jsdoc, a few options, such as, exemptedBy and contexts, may be used across different rules.

eslint-plugin-jsdoc options, if present, are in the form of an object supplied as the second argument in an array after the error level.

// `.eslintrc.js`
{
  rules: {
    'jsdoc/require-example': [
        // The Error level should be `error`, `warn`, or `off` (or 2, 1, or 0)
        'error',
        // The options vary by rule, but are added to an options object:
        {
          avoidExampleOnConstructors: true,
          exemptedBy: ['type']
        }
    ]
  }
}

Settings

Allow @private to disable rules for that comment block

  • settings.jsdoc.ignorePrivate - Disables all rules for the comment block on which a @private tag (or @access private) occurs. Defaults to false. Note: This has no effect with the rule check-access (whose purpose is to check access modifiers).

maxLines and minLines

One can use minLines and maxLines to indicate how many line breaks (if any) will be checked to find a jsdoc comment block before the given code block. These settings default to 0 and 1 respectively.

In conjunction with the require-jsdoc rule, these settings can be enforced so as to report problems if a jsdoc block is not found within the specified boundaries. The settings are also used in the fixer to determine how many line breaks to add when a block is missing.

Mode

  • settings.jsdoc.mode - Set to jsdoc (the default), typescript, or closure. Currently is used for the following:
    • Determine valid tags for check-tag-names
    • Only check @template in no-undefined-types for types in "closure" and "typescript" modes
    • For type-checking rules, determine which tags will be checked for types (Closure allows types on some tags which the others do not, so these tags will additionally be checked in "closure" mode)
    • Check preferred tag names

Alias Preference

Use settings.jsdoc.tagNamePreference to configure a preferred alias name for a JSDoc tag. The format of the configuration is: <primary tag name>: <preferred alias name>, e.g.

{
    "rules": {},
    "settings": {
        "jsdoc": {
            "tagNamePreference": {
                "param": "arg",
                "returns": "return"
            }
        }
    }
}

Note: ESLint does not allow settings to have keys which conflict with Object.prototype e.g. 'constructor'. To work around this, you can use the key 'tag constructor'.

One may also use an object with a message and replacement.

The following will report the message @extends is to be used over @augments as it is more evocative of classes than @augments upon encountering @augments.

{
    "rules": {},
    "settings": {
        "jsdoc": {
            "tagNamePreference": {
                "augments": {
                  "message": "@extends is to be used over @augments as it is more evocative of classes than @augments",
                  "replacement": "extends"
                }
            }
        }
    }
}

If one wishes to reject a normally valid tag, e.g., @todo, one may set the tag to false:

{
    "rules": {},
    "settings": {
        "jsdoc": {
            "tagNamePreference": {
                "todo": false
            }
        }
    }
}

A project wishing to ensure no blocks are left excluded from entering the documentation, might wish to prevent the @ignore tag in the above manner.

Or one may set the targeted tag to an object with a custom message, but without a replacement property:

{
    "rules": {},
    "settings": {
        "jsdoc": {
            "tagNamePreference": {
                "todo": {
                  "message": "We expect immediate perfection, so don't leave to-dos in your code."
                }
            }
        }
    }
}

Note that the preferred tags indicated in the settings.jsdoc.tagNamePreference map will be assumed to be defined by check-tag-names.

See check-tag-names for how that fact can be used to set an alias to itself to allow both the alias and the default (since aliases are otherwise not permitted unless used in tagNamePreference).

Default Preferred Aliases

The defaults in eslint-plugin-jsdoc (for tags which offer aliases) are as follows:

  • @abstract (over @virtual)
  • @augments (over @extends)
  • @class (over @constructor)
  • @constant (over @const)
  • @default (over @defaultvalue)
  • @description (over @desc)
  • @external (over @host)
  • @file (over @fileoverview, @overview)
  • @fires (over @emits)
  • @function (over @func, @method)
  • @member (over @var)
  • @param (over @arg, @argument)
  • @property (over @prop)
  • @returns (over @return)
  • @throws (over @exception)
  • @yields (over @yield)

This setting is utilized by the the rule for tag name checking (check-tag-names) as well as in the @param and @require rules:

  • check-param-names
  • check-tag-names
  • require-hyphen-before-param-description
  • require-description
  • require-param
  • require-param-description
  • require-param-name
  • require-param-type
  • require-returns
  • require-returns-check
  • require-returns-description
  • require-returns-type

@override/@augments/@extends/@implements Without Accompanying @param/@description/@example/@returns

The following settings allows the element(s) they reference to be omitted on the JSDoc comment block of the function or that of its parent class for any of the "require" rules (i.e., require-param, require-description, require-example, or require-returns).

  • settings.jsdoc.overrideReplacesDocs (@override) - Defaults to true
  • settings.jsdoc.augmentsExtendsReplacesDocs (@augments or its alias @extends) - Defaults to false.
  • settings.jsdoc.implementsReplacesDocs (@implements) - Defaults to false

The format of the configuration is as follows:

{
    "rules": {},
    "settings": {
        "jsdoc": {
            "overrideReplacesDocs": true,
            "augmentsExtendsReplacesDocs": true,
            "implementsReplacesDocs": true
        }
    }
}

Settings to Configure check-types and no-undefined-types

  • settings.jsdoc.preferredTypes An option map to indicate preferred or forbidden types (if default types are indicated here, these will have precedence over the default recommendations for check-types). The keys of this map are the types to be replaced (or forbidden). These keys may include:

    1. The "ANY" type, *
    2. The pseudo-type [] which we use to denote the parent (array) types used in the syntax string[], number[], etc.
    3. The pseudo-type .<> (or .) to represent the format Array.<value> or Object.<key, value>
    4. The pseudo-type <> to represent the format Array<value> or Object<key, value>
    5. A plain string type, e.g., MyType
    6. A plain string type followed by one of the above pseudo-types (except for [] which is always assumed to be an Array), e.g., Array., or SpecialObject<>.

    If a bare pseudo-type is used, it will match all parent types of that form. If a pseudo-type prefixed with a type name is used, it will only match parent types of that form and type name.

    The values can be:

    • false to forbid the type
    • a string to indicate the type that should be preferred in its place (and which fix mode can replace); this can be one of the formats of the keys described above.
      • Note that the format will not be changed unless you use a pseudo-type in the replacement. (For example, 'Array.<>': 'MyArray' will change Array.<string> to MyArray.<string>, preserving the dot. To get rid of the dot, you must use the pseudo-type with <>, i.e., 'Array.<>': 'MyArray<>', which will change Array.<string> to MyArray<string>).
      • If you use a bare pseudo-type in the replacement (e.g., 'MyArray.<>': '<>'), the type will be converted to the format of the pseudo-type without changing the type name. For example, MyArray.<string> will become MyArray<string> but Array.<string> will not be modified.
    • an object with:
      • the key message to provide a specific error message when encountering the discouraged type.
        • The message string will have the substrings with special meaning, {{tagName}} and {{tagValue}}, replaced with their corresponding value.
      • an optional key replacement with either of the following values:
        • a string type to be preferred in its place (and which fix mode can replace)
        • false (for forbidding the type)

Note that the preferred types indicated as targets in settings.jsdoc.preferredTypes map will be assumed to be defined by no-undefined-types.

See the option of check-types, unifyParentAndChildTypeChecks, for how the keys of preferredTypes may have <> or .<> (or just .) appended and its bearing on whether types are checked as parents/children only (e.g., to match Array if the type is Array vs. Array.<string>).

Advanced

AST and Selectors

For various rules, one can add to the environments to which the rule applies by using the contexts option.

This option works with ESLint's selectors which are esquery expressions one may use to target a specific node type or types, including subsets of the type(s) such as nodes with certain children or attributes.

These expressions are used within ESLint plugins to find those parts of your files' code which are of interest to check. However, in eslint-plugin-jsdoc, we also allow you to use these selectors to define additional contexts where you wish our own rules to be applied.

To know all of the AST definitions one may target, it will depend on the parser you are using with ESLint (e.g., espree is the default parser for ESLint, and this follows EStree AST but to support the the latest experimental features of JavaScript, one may use babel-eslint or to be able to have one's rules (including JSDoc rules) apply to TypeScript, one may use @typescript-eslint/parser, etc.

So you can look up a particular parser to see its rules, e.g., browse through the ESTree docs as used by Espree or see ESLint's overview of the structure of AST.

However, it can sometimes be even more helpful to get an idea of ASt by just providing some of your JavaScript to the wonderful AST Explorer tool and see what AST is built out of your code. You can set the tool to the specific parser which you are using.

And if you wish to introspect on the AST of code within your projects, you can use eslint-plugin-query. Though it also works as a plugin, you can use it with its own CLI, e.g., to search your files for matching esquery selectors, optionally showing it as AST JSON.

Tip: If you want to more deeply understand not just the resulting AST tree structures for any given code but also the syntax for esquery selectors so that you can, for example, find only those nodes with a child of a certain type, you can set the "Transform" feature to ESLint and test out esquery selectors in place of the selector expression (e.g., replace 'VariableDeclaration > VariableDeclarator > Identifier[name="someVar"]' as we have here) to the selector you wish so as to get messages reported in the bottom right pane which match your esquery selector).

Rules

check-access

Checks that @access tags use one of the following values:

  • "package", "private", "protected", "public"

Also reports:

  • Mixing of @access with @public, @private, @protected, or @package on the same doc block.
  • Use of multiple instances of @access (or the @public, etc. style tags) on the same doc block.
Context everywhere
Tags @access
Settings
Options

The following patterns are considered problems:

/**
 * @access foo
 */
function quux (foo) {

}
// Message: Missing valid JSDoc @access level.

/**
 * @access foo
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"ignorePrivate":true}}
// Message: Missing valid JSDoc @access level.

/**
 * @accessLevel foo
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"tagNamePreference":{"access":"accessLevel"}}}
// Message: Missing valid JSDoc @accessLevel level.

/**
 * @access
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"tagNamePreference":{"access":false}}}
// Message: Unexpected tag `@access`

class MyClass {
  /**
   * @access
   */
  myClassField = 1
}
// Message: Missing valid JSDoc @access level.

/**
 * @access public
 * @public
 */
function quux (foo) {

}
// Message: The @access tag may not be used with specific access-control tags (@package, @private, @protected, or @public).

/**
 * @access public
 * @access private
 */
function quux (foo) {

}
// Message: At most one access-control tag may be present on a jsdoc block.

/**
 * @access public
 * @access private
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"ignorePrivate":true}}
// Message: At most one access-control tag may be present on a jsdoc block.

/**
 * @public
 * @private
 */
function quux (foo) {

}
// Message: At most one access-control tag may be present on a jsdoc block.

/**
 * @public
 * @private
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"ignorePrivate":true}}
// Message: At most one access-control tag may be present on a jsdoc block.

/**
 * @public
 * @public
 */
function quux (foo) {

}
// Message: At most one access-control tag may be present on a jsdoc block.

The following patterns are not considered problems:

/**
 *
 */
function quux (foo) {

}

/**
 * @access public
 */
function quux (foo) {

}

/**
 * @accessLevel package
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"tagNamePreference":{"access":"accessLevel"}}}

class MyClass {
  /**
   * @access private
   */
  myClassField = 1
}

/**
 * @public
 */
function quux (foo) {

}

/**
 * @private
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"ignorePrivate":true}}

check-alignment

Reports invalid alignment of JSDoc block asterisks.

Context everywhere
Tags N/A

The following patterns are considered problems:

/**
  * @param {Number} foo
 */
function quux (foo) {
  // with spaces
}
// Message: Expected JSDoc block to be aligned.

/**
  * @param {Number} foo
 */
function quux (foo) {
	// with tabs
}
// Message: Expected JSDoc block to be aligned.

/**
  * @param {Number} foo
 */
function quux (foo) {
  // with spaces
}
// Message: Expected JSDoc block to be aligned.

/**
* @param {Number} foo
*/
function quux (foo) {
  // with spaces
}
// Message: Expected JSDoc block to be aligned.

/**
 * @param {Number} foo
  */
function quux (foo) {

}
// Message: Expected JSDoc block to be aligned.

 /**
 * @param {Number} foo
 */
function quux (foo) {

}
// Message: Expected JSDoc block to be aligned.

 /**
  * @param {Number} foo
 */
function quux (foo) {

}
// Message: Expected JSDoc block to be aligned.

/**
  * @param {Number} foo
  */
 function quux (foo) {

 }
// Message: Expected JSDoc block to be aligned.

/**
   * A jsdoc not attached to any node.
 */
// Message: Expected JSDoc block to be aligned.

class Foo {
  /**
   *  Some method
    * @param a
   */
  quux(a) {}
}
// Message: Expected JSDoc block to be aligned.

The following patterns are not considered problems:

/**
 * Desc
 *
 * @param {Number} foo
 */
function quux (foo) {

}

/**
 * Desc
 *
 * @param {{
  foo: Bar,
  bar: Baz
 * }} foo
 *
 */
function quux (foo) {

}

/*  <- JSDoc must start with 2 stars.
  *    So this is unchecked.
 */
function quux (foo) {}

/**
  * @param {Number} foo
  * @private
 */
function quux (foo) {
  // with spaces
}
// Settings: {"jsdoc":{"ignorePrivate":true}}

/**
  * @param {Number} foo
  * @access private
 */
function quux (foo) {
  // with spaces
}
// Settings: {"jsdoc":{"ignorePrivate":true}}

check-examples

Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules.

Options

The options below all default to no-op/false except as noted.

captionRequired

JSDoc specs use of an optional <caption> element at the beginning of @example.

The option captionRequired insists on a <caption> being present at the beginning of any @example.

exampleCodeRegex and rejectExampleCodeRegex

JSDoc does not specify a formal means for delimiting code blocks within @example (it uses generic syntax highlighting techniques for its own syntax highlighting). The following options determine whether a given @example tag will have the check-examples checks applied to it:

  • exampleCodeRegex - Regex which whitelists lintable examples. If a parenthetical group is used, the first one will be used, so you may wish to use (?:...) groups where you do not wish the first such group treated as one to include. If no parenthetical group exists or matches, the whole matching expression will be used. An example might be "^```(?:js|javascript)([\\s\\S]*)```\s*$" to only match explicitly fenced JavaScript blocks. Defaults to only using the u flag, so to add your own flags, encapsulate your expression as a string, but like a literal, e.g., /```js.*```/gi. Note that specifying a global regular expression (i.e., with g) will allow independent linting of matched blocks within a single @example.
  • rejectExampleCodeRegex - Regex blacklist which rejects non-lintable examples (has priority over exampleCodeRegex). An example might be "^`" to avoid linting fenced blocks which may indicate a non-JavaScript language. See exampleCodeRegex on how to add flags if the default u is not sufficient.

If neither is in use, all examples will be matched. Note also that even if captionRequired is not set, any initial <caption> will be stripped out before doing the regex matching.

paddedIndent

This integer property allows one to add a fixed amount of whitespace at the beginning of the second or later lines of the example to be stripped so as to avoid linting issues with the decorative whitespace. For example, if set to a value of 4, the initial whitespace below will not trigger indent rule errors as the extra 4 spaces on each subsequent line will be stripped out before evaluation.

/**
 * @example
 *     anArray.filter((a) => {
 *      return a.b;
 *     });
 */

reportUnusedDisableDirectives

If not set to false, reportUnusedDisableDirectives will report disabled directives which are not used (and thus not needed). Defaults to true. Corresponds to ESLint's --report-unused-disable-directives.

Inline ESLint config within @example JavaScript is allowed, though the disabling of ESLint directives which are not needed by the resolved rules will be reported as with the ESLint --report-unused-disable-directives command.

Options for Determining ESLint Rule Applicability (allowInlineConfig, noDefaultExampleRules, matchingFileName, configFile, checkEslintrc, and baseConfig)

The following options determine which individual ESLint rules will be applied to the JavaScript found within the @example tags (as determined to be applicable by the above regex options). They are ordered by decreasing precedence:

  • allowInlineConfig - If not set to false, will allow inline config within the @example to override other config. Defaults to true.
  • noDefaultExampleRules - Setting to true will disable the default rules which are expected to be troublesome for most documentation use. See the section below for the specific default rules.
  • configFile - A config file. Corresponds to ESLint's -c.
  • matchingFileName - Option for a file name (even non-existent) to trigger specific rules defined in one's config; usable with ESLint .eslintrc.* overrides -> files globs, to apply a desired subset of rules with @example (besides allowing for rules specific to examples, this option can be useful for enabling reuse of the same rules within @example as with JavaScript Markdown lintable by other plugins, e.g., if one sets matchingFileName to dummy.md so that @example rules will follow one's Markdown rules).
  • checkEslintrc - Defaults to true in adding rules based on an .eslintrc.* file. Setting to false corresponds to ESLint's --no-eslintrc. If matchingFileName is set, this will automatically be true and will use the config corresponding to that file. If matchingFileName is not set and this value is set to false, the .eslintrc.* configs will not be checked. If matchingFileName is not set, and this is unset or set to true, the .eslintrc.* configs will be checked as though the file name were the same as the file containing the example, with any file extension changed to ".md" (and if there is no file extension, "dummy.md" will be used). This allows convenient sharing of similar rules with often also context-free Markdown as well as use of overrides as described under matchingFileName. Note that this option (whether set by matchingFileName or set manually to true) may come at somewhat of a performance penalty as the file's existence is checked by eslint.
  • baseConfig - Set to an object of rules with the same schema as .eslintrc.* for defaults.

Rules Disabled by Default Unless noDefaultExampleRules is Set to true
  • eol-last - Insisting that a newline "always" be at the end is less likely to be desired in sample code as with the code file convention.
  • no-console - This rule is unlikely to have inadvertent temporary debugging within examples.
  • no-multiple-empty-lines - This rule may be problematic for projects which use an initial newline just to start an example. Also, projects may wish to use extra lines within examples just for easier illustration purposes.
  • no-undef - Many variables in examples will be undefined.
  • no-unused-vars - It is common to define variables for clarity without always using them within examples.
  • padded-blocks - It can generally look nicer to pad a little even if one's code follows more stringency as far as block padding.
  • import/no-unresolved - One wouldn't generally expect example paths to resolve relative to the current JavaScript file as one would with real code.
  • import/unambiguous - Snippets in examples are likely too short to always include full import/export info.
  • node/no-missing-import - See import/no-unresolved.
  • node/no-missing-require - See import/no-unresolved.
Context everywhere
Tags example
Options See above

The following patterns are considered problems:

/**
 * @example alert('hello')
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"no-alert":2,"semi":["error","always"]}},"checkEslintrc":false}]
// Message: @example error (no-alert): Unexpected alert.

/**
 * @example alert('hello')
 */
class quux {

}
// Options: [{"baseConfig":{"rules":{"no-alert":2,"semi":["error","always"]}},"checkEslintrc":false}]
// Message: @example error (no-alert): Unexpected alert.

/**
 * @example ```js
 alert('hello');
 ```
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["error","never"]}},"checkEslintrc":false,"exampleCodeRegex":"```js([\\s\\S]*)```"}]
// Message: @example error (semi): Extra semicolon.

/**
 * @example
 *
 * ```js alert('hello'); ```
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["error","never"]}},"checkEslintrc":false,"exampleCodeRegex":"```js ([\\s\\S]*)```"}]
// Message: @example error (semi): Extra semicolon.

/**
 * @example
 * ```js alert('hello'); ```
 */
var quux = {

};
// Options: [{"baseConfig":{"rules":{"semi":["error","never"]}},"checkEslintrc":false,"exampleCodeRegex":"```js ([\\s\\S]*)```"}]
// Message: @example error (semi): Extra semicolon.

/**
 * @example ```
 * js alert('hello'); ```
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["error","never"]}},"checkEslintrc":false,"exampleCodeRegex":"```\njs ([\\s\\S]*)```"}]
// Message: @example error (semi): Extra semicolon.

/**
 * @example <b>Not JavaScript</b>
 */
function quux () {

}
/**
 * @example quux2();
 */
function quux2 () {

}
// Options: [{"baseConfig":{"rules":{"semi":["error","never"]}},"checkEslintrc":false,"rejectExampleCodeRegex":"^\\s*<.*>\\s*$"}]
// Message: @example error (semi): Extra semicolon.

/**
 * @example
 * quux(); // does something useful
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"no-undef":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":true}]
// Message: @example error (no-undef): 'quux' is not defined.

/**
 * @example <caption>Valid usage</caption>
 * quux(); // does something useful
 *
 * @example
 * quux('random unwanted arg'); // results in an error
 */
function quux () {

}
// Options: [{"captionRequired":true,"checkEslintrc":false}]
// Message: Caption is expected for examples.

/**
 * @example  quux();
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"indent":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":false}]
// Message: @example error (indent): Expected indentation of 0 spaces but found 1.

/**
 * @example test() // eslint-disable-line semi
 */
function quux () {}
// Options: [{"checkEslintrc":false,"noDefaultExampleRules":true,"reportUnusedDisableDirectives":true}]
// Message: @example error: Unused eslint-disable directive (no problems were reported from 'semi').

/**
 * @example
 test() // eslint-disable-line semi
 */
function quux () {}
// Options: [{"allowInlineConfig":false,"baseConfig":{"rules":{"semi":["error","always"]}},"checkEslintrc":false,"noDefaultExampleRules":true}]
// Message: @example error (semi): Missing semicolon.

/**
 * @example const i = 5;
 * quux2()
 */
function quux2 () {

}
// Options: [{"matchingFileName":"../../jsdocUtils.js"}]
// Message: @example warning (id-length): Identifier name 'i' is too short (< 2).

/**
 * @example const i = 5;
 * quux2()
 */
function quux2 () {

}
// Message: @example warning (id-length): Identifier name 'i' is too short (< 2).

/**
 * @example const i = 5;
 *   quux2()
 */
function quux2 () {

}
// Options: [{"paddedIndent":2}]
// Message: @example warning (id-length): Identifier name 'i' is too short (< 2).

/**
 * @example
 * const i = 5;
 * quux2()
 */
function quux2 () {

}
// Message: @example warning (id-length): Identifier name 'i' is too short (< 2).

/**
 * @example const idx = 5;
 * quux2()
 */
function quux2 () {

}
// Options: [{"matchingFileName":"dummy.js"}]
// Message: @example error (semi): Missing semicolon.

/**
 * @example const idx = 5;
 *
 * quux2()
 */
function quux2 () {

}
// Options: [{"matchingFileName":"dummy.js"}]
// Message: @example error (semi): Missing semicolon.

/**
 * @example const idx = 5;
 *
 * quux2()
 */
function quux2 () {

}
// Options: [{"checkEslintrc":false,"matchingFileName":"dummy.js"}]
// Message: @example error: Parsing error: The keyword 'const' is reserved

/**
 * @example // begin
 alert('hello')
 // end
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["warn","always"]}},"checkEslintrc":false,"exampleCodeRegex":"// begin[\\s\\S]*// end","noDefaultExampleRules":true}]
// Message: @example warning (semi): Missing semicolon.

/**
 *
 */
function f () {

}
// Settings: {"jsdoc":{"allowInlineConfig":true,"baseConfig":{},"captionRequired":false,"configFile":"configFile.js","eslintrcForExamples":true,"exampleCodeRegex":".*?","matchingFileName":"test.md","noDefaultExampleRules":false,"rejectExampleCodeRegex":"\\W*","reportUnusedDisableDirectives":true}}
// Message: `settings.jsdoc.captionRequired` has been removed, use options in the rule `check-examples` instead.

/**
 * @typedef {string} Foo
 * @example <caption></caption>
 * 'foo'
 */
// Options: [{"captionRequired":true,"checkEslintrc":false}]
// Message: Caption is expected for examples.

/**
 * @example
 * const list: number[] = [1, 2, 3]
 * quux(list);
 */
function quux () {

}
// Options: [{"baseConfig":{"parser":"@typescript-eslint/parser","parserOptions":{"ecmaVersion":6},"rules":{"semi":["error","always"]}},"checkEslintrc":false}]
// Message: @example error (semi): Missing semicolon.

/**
 * @example
 * const test = something?.find((_) => {
 *   return _
 * });
 */
function quux () {

}
// Options: [{"baseConfig":{"parserOptions":{"ecmaVersion":6},"rules":{"semi":["error","always"]}}}]
// Message: @example error (semi): Missing semicolon.

/**
 * @example <caption>Say `Hello!` to the user.</caption>
 * First, import the function:
 *
 * ```js
 * import popup from './popup'
 * const aConstInSameScope = 5;
 * ```
 *
 * Then use it like this:
 *
 * ```js
 * const aConstInSameScope = 7;
 * popup('Hello!')
 * ```
 *
 * Here is the result on macOS:
 *
 * ![Screenshot](path/to/screenshot.jpg)
 */
// Options: [{"baseConfig":{"parserOptions":{"ecmaVersion":2015,"sourceType":"module"},"rules":{"semi":["error","always"]}},"checkEslintrc":false,"exampleCodeRegex":"/^```(?:js|javascript)\\n([\\s\\S]*?)```$/gm"}]
// Message: @example error (semi): Missing semicolon.

/**
 * @example // begin
 alert('hello')
 // end
 * And here is another example:
 // begin
 alert('there')
 // end
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["warn","always"]}},"checkEslintrc":false,"exampleCodeRegex":"/\\/\\/ begin[\\s\\S]*?// end/g","noDefaultExampleRules":true}]
// Message: @example warning (semi): Missing semicolon.

/**
 * @example
 *   quux();
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"indent":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":false}]
// Message: @example error (indent): Expected indentation of 0 spaces but found 2.

The following patterns are not considered problems:

/**
 * @example ```js
 alert('hello');
 ```
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["error","always"]}},"checkEslintrc":false,"exampleCodeRegex":"```js([\\s\\S]*)```"}]

/**
 * @example ```js
 alert('hello');
 ```
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"semi":["error","always"]}},"checkEslintrc":false,"exampleCodeRegex":"/```js([\\s\\S]*)```/"}]

/**
 * @example
 * // arbitrary example content
 */
function quux () {

}
// Options: [{"checkEslintrc":false}]

/**
 * @example
 * quux(); // does something useful
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"no-undef":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":false}]

/**
 * @example quux();
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"indent":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":false}]

/**
 * @example <caption>Valid usage</caption>
 * quux(); // does something useful
 *
 * @example <caption>Invalid usage</caption>
 * quux('random unwanted arg'); // results in an error
 */
function quux () {

}
// Options: [{"captionRequired":true,"checkEslintrc":false}]

/**
 * @example test() // eslint-disable-line semi
 */
function quux () {}
// Options: [{"checkEslintrc":false,"noDefaultExampleRules":true,"reportUnusedDisableDirectives":false}]

/**
 * @example
 test() // eslint-disable-line semi
 */
function quux () {}
// Options: [{"allowInlineConfig":true,"baseConfig":{"rules":{"semi":["error","always"]}},"checkEslintrc":false,"noDefaultExampleRules":true}]

/**
 * @example ```js
 alert('hello')
 ```
 */
var quux = {

};
// Options: [{"baseConfig":{"rules":{"semi":["error","never"]}},"checkEslintrc":false,"exampleCodeRegex":"```js([\\s\\S]*)```"}]

/**
 * @example
 * foo(function (err) {
 *     throw err;
 * });
 */
function quux () {}
// Options: [{"baseConfig":{"rules":{"indent":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":false}]

/**
 * @example
 * const list: number[] = [1, 2, 3];
 * quux(list);
 */
function quux () {

}
// Options: [{"baseConfig":{"parser":"@typescript-eslint/parser","parserOptions":{"ecmaVersion":6},"rules":{"semi":["error","always"]}},"checkEslintrc":false}]

/**
 * @example const ident = 5;
 *   quux2();
 *   bar();
 */
function quux2 () {

}
// Options: [{"paddedIndent":2}]

/**
 * @example
 * function quux() {
 *     bar();
 * }
 */
function quux () {

}
// Options: [{"baseConfig":{"rules":{"indent":["error"]}},"checkEslintrc":false,"noDefaultExampleRules":false}]

// Comment
a();

export default {};

check-indentation

Reports invalid padding inside JSDoc blocks.

Ignores parts enclosed in Markdown "code block"'s. For example, the following description is not reported:

/**
 * Some description:
 * ```html
 * <section>
 *   <title>test</title>
 * </section>
 * ```
 */

Options

This rule has an object option.

excludeTags

Array of tags (e.g., ['example', 'description']) whose content will be "hidden" from the check-indentation rule. Defaults to ['example'].

By default, the whole JSDoc block will be checked for invalid padding. That would include @example blocks too, which can get in the way of adding full, readable examples of code without ending up with multiple linting issues.

When disabled (by passing excludeTags: [] option), the following code will report a padding issue:

/**
 * @example
 * anArray.filter((a) => {
 *   return a.b;
 * });
 */
Context everywhere
Tags N/A
Options excludeTags

The following patterns are considered problems:

/**  foo */
function quux () {

}
// Message: There must be no indentation.

/**
 * foo
 *
 * @param bar
 *  baz
 */
function quux () {

}
// Message: There must be no indentation.

/**
 * Foo
 *   bar
 */
class Moo {}
// Message: There must be no indentation.

/**
 * foo
 *
 * @example
 * anArray.filter((a) => {
 *   return a.b;
 * });
 */
function quux () {

}
// Options: [{"excludeTags":[]}]
// Message: There must be no indentation.

/**
 * foo
 *
 * @example
 *   aaaa
 * @returns
 *   eeee
 */
function quux () {

}
// Message: There must be no indentation.

/**
 * foo
 * ```html
 * <section>
 *   <title>test</title>
 * </section>
 * ```
 * @returns
 *   eeee
 */
function quux () {

}
// Message: There must be no indentation.

/**
 * foo
 * ```   aaaa```
 * @returns
 *   eeee
 */
function quux () {

}
// Message: There must be no indentation.

/**
* @example <caption>
* Here is a long
*   indented summary of this
* example
* </caption>
* ```js
* function hi () {
*   alert('Hello');
* }
* ```
*/
// Options: [{"excludeTags":[]}]
// Message: There must be no indentation.

/**
* @example <caption>
* Here is a long
* summary of this
* example
* </caption>
* // Code is not wrapped into fenced code block
* function hi () {
*   alert('Hello');
* }
*/
// Options: [{"excludeTags":[]}]
// Message: There must be no indentation.

The following patterns are not considered problems:

/**
 * foo
 *
 * @param bar
 * baz
 */
function quux () {

}

/*** foo */
function quux () {

}

/**
 * foo
 *
 * @example
 * anArray.filter((a) => {
 *   return a.b;
 * });
 */
function quux () {

}

/**
 * foo
 *
 * @example
 * anArray.filter((a) => {
 *   return a.b;
 * });
 * @returns
 *   eeee
 */
function quux () {

}
// Options: [{"excludeTags":["example","returns"]}]

/**
 * foo
 * ```html
 * <section>
 *   <title>test</title>
 * </section>
 * ```
 * @returns eeee
 */
function quux () {

}

/**
 * foo
 * ```   aaaa```
 * @returns eeee
 */
function quux () {

}

/**
* @example <caption>
* Here is a long
* summary of this
* example
* </caption>
* ```js
* function hi () {
*   alert('Hello');
* }
* ```
*/
// Options: [{"excludeTags":[]}]

check-param-names

Ensures that parameter names in JSDoc match those in the function declaration.

Destructuring

Note that by default the rule will not report parameters present on the docs but non-existing on the function signature when an object rest property is part of that function signature since the seemingly non-existing properties might actually be a part of the object rest property.

/**
 * @param options
 * @param options.foo
 */
function quux ({foo, ...extra}) {}

To require that extra be documented--and that any extraneous properties get reported--e.g., if there had been a @param options.bar above--you can use the checkRestProperty option which insists that the rest property be documented (and that there be no other implicit properties). Note, however, that jsdoc does not appear to currently support syntax or output to distinguish rest properties from other properties, so in looking at the docs alone without looking at the function signature, the disadvantage of enabling this option is that it may appear that there is an actual property named extra.

Options

checkRestProperty

See the "Destructuring" section. Defaults to false.

checkTypesPattern

See require-param under the option of the same name.

enableFixer

Set to true to auto-remove @param duplicates (based on identical names).

Note that this option will remove duplicates of the same name even if the definitions do not match in other ways (e.g., the second param will be removed even if it has a different type or description).

allowExtraTrailingParamDocs

If set to true, this option will allow extra @param definitions (e.g., representing future expected or virtual params) to be present without needing their presence within the function signature. Other inconsistencies between @param's and present function parameters will still be reported.

Context ArrowFunctionExpression, FunctionDeclaration, FunctionExpression
Options allowExtraTrailingParamDocs, checkRestProperty, checkTypesPattern
Tags param

The following patterns are considered problems:

/**
 * @param Foo
 */
function quux (foo = 'FOO') {

}
// Message: Expected @param names to be "foo". Got "Foo".

/**
 * @arg Foo
 */
function quux (foo = 'FOO') {

}
// Settings: {"jsdoc":{"tagNamePreference":{"param":"arg"}}}
// Message: Expected @arg names to be "foo". Got "Foo".

/**
 * @param Foo
 */
function quux (foo) {

}
// Message: Expected @param names to be "foo". Got "Foo".

/**
 * @param Foo.Bar
 */
function quux (foo) {

}
// Message: @param path declaration ("Foo.Bar") appears before any real parameter.

/**
 * @param foo
 * @param Foo.Bar
 */
function quux (foo) {

}
// Message: @param path declaration ("Foo.Bar") root node name ("Foo") does not match previous real parameter name ("foo").

/**
 * Assign the project to a list of employees.
 * @param {string} employees[].name - The name of an employee.
 * @param {string} employees[].department - The employee's department.
 */
function assign (employees) {

};
// Message: @param path declaration ("employees[].name") appears before any real parameter.

/**
 * Assign the project to a list of employees.
 * @param {string} employees[].name - The name of an employee.
 * @param {string} employees[].name - The employee's department.
 */
function assign (employees) {

};
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "employees[].name"

/**
 * @param foo
 * @param foo.bar
 * @param bar
 */
function quux (bar, foo) {

}
// Message: Expected @param names to be "bar, foo". Got "foo, bar".

/**
 * @param foo
 * @param bar
 */
function quux (foo) {

}
// Message: @param "bar" does not match an existing function parameter.

/**
 * @param foo
 * @param foo
 */
function quux (foo) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "foo"

class bar {
    /**
     * @param foo
     * @param foo
     */
    quux (foo) {

    }
}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "foo"

/**
 * @param foo
 * @param foo
 */
function quux (foo, bar) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "foo"

/**
 * @param foo
 * @param foo
 */
function quux (foo, foo) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "foo"

/**
 * @param cfg
 * @param cfg.foo
 * @param cfg.foo
 */
function quux ({foo}) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "cfg.foo"

/**
 * @param cfg
 * @param cfg.foo
 * @param cfg.foo
 */
function quux ({foo}) {

}
// Message: Duplicate @param "cfg.foo"

/**
 * @param cfg
 * @param cfg.foo
 */
function quux ({foo, bar}) {

}
// Message: Missing @param "cfg.bar"

/**
 * @param cfg
 * @param cfg.foo
 * @param [cfg.foo]
 * @param baz
 */
function quux ({foo}, baz) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "cfg.foo"

/**
 * @param cfg
 * @param cfg.foo
 * @param [cfg.foo="with a default"]
 * @param baz
 */
function quux ({foo, bar}, baz) {

}
// Message: Missing @param "cfg.bar"

/**
 * @param cfg
 * @param cfg.foo
 * @param [cfg.foo="with a default"]
 * @param baz
 */
function quux ({foo}, baz) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @param "cfg.foo"

/**
 * @param cfg
 * @param [cfg.foo="with a default"]
 * @param baz
 */
function quux ({foo, bar}, baz) {

}
// Message: Missing @param "cfg.bar"

/**
 * @param args
 */
function quux ({a, b}) {

}
// Message: Missing @param "args.a"

/**
 * @param args
 */
function quux ({a, b} = {}) {

}
// Message: Missing @param "args.a"

export class SomeClass {
  /**
   * @param prop
   */
  constructor(private property: string) {}
}
// Message: Expected @param names to be "property". Got "prop".

export class SomeClass {
  /**
   * @param prop
   * @param prop.foo
   */
  constructor(prop: { foo: string, bar: string }) {}
}
// Message: Missing @param "prop.bar"

export class SomeClass {
  /**
   * @param prop
   * @param prop.foo
   * @param prop.bar
   */
  constructor(options: { foo: string, bar: string }) {}
}
// Message: Missing @param "options.foo"

export class SomeClass {
  /**
   * @param options
   * @param options.foo
   * @param options.bar
   */
  constructor(options: { foo: string }) {}
}
// Message: @param "options.bar" does not exist on options

/**
 * @param foo
 */
function quux (foo) {

}
// Settings: {"jsdoc":{"tagNamePreference":{"param":false}}}
// Message: Unexpected tag `@param`

/**
 * @param {Error} error Exit code
 * @param {number} [code = 1] Exit code
 */
function quux (error, cde = 1) {
};
// Message: Expected @param names to be "error, cde". Got "error, code".

/**
 * @param foo
 */
function quux ([a, b] = []) {

}
// Message: Missing @param "foo.0"

/**
 * @param options
 * @param options.foo
 */
function quux ({foo, ...extra}) {
}
// Options: [{"checkRestProperty":true}]
// Message: Missing @param "options.extra"

/**
 * @param cfg
 * @param cfg.foo
 * @param cfg.bar
 * @param cfg.extra
 */
function quux ({foo, ...extra}) {

}
// Options: [{"checkRestProperty":true}]
// Message: @param "cfg.bar" does not exist on cfg

/**
 * Converts an SVGRect into an object.
 * @param {SVGRect} bbox - a SVGRect
 */
const bboxToObj = function ({x, y, width, height}) {
  return {x, y, width, height};
};
// Options: [{"checkTypesPattern":"SVGRect"}]
// Message: Missing @param "bbox.x"

/**
 * Converts an SVGRect into an object.
 * @param {object} bbox - a SVGRect
 */
const bboxToObj = function ({x, y, width, height}) {
  return {x, y, width, height};
};
// Message: Missing @param "bbox.x"

module.exports = class GraphQL {
  /**
   * @param fetchOptions
   * @param cacheKey
   */
  fetch = ({ url, ...options }, cacheKey) => {
  }
};
// Options: [{"checkRestProperty":true}]
// Message: Missing @param "fetchOptions.url"

The following patterns are not considered problems:

/**
 *
 */
function quux (foo) {

}

/**
 * @param foo
 */
function quux (foo) {

}

/**
 * @param foo
 * @param bar
 */
function quux (foo, bar) {

}

/**
 * @param foo
 * @param bar
 */
function quux (foo, bar, baz) {

}

/**
 * @param foo
 * @param foo.foo
 * @param bar
 */
function quux (foo, bar) {

}

/**
 * @param args
 */
function quux (...args) {

}

/**
 * @param foo
 * @param foo.a
 * @param foo.b
 */
function quux ({a, b}) {

}

/**
 * @param foo
 * @param foo.bar
 * @param foo.baz
 * @param bar
 */
function quux (foo, bar) {

}

/**
 * Assign the project to a list of employees.
 * @param {object[]} employees - The employees who are responsible for the project.
 * @param {string} employees[].name - The name of an employee.
 * @param {string} employees[].department - The employee's department.
 */
function assign (employees) {

};

export class SomeClass {
  /**
   * @param property
   */
  constructor(private property: string) {}
}

export class SomeClass {
  /**
   * @param options
   * @param options.foo
   * @param options.bar
   */
  constructor(options: { foo: string, bar: string }) {}
}

export class SomeClass {
  /**
   * @param options
   * @param options.foo
   * @param options.bar
   */
  constructor({ foo, bar }: { foo: string, bar: string }) {}
}

export class SomeClass {
  /**
   * @param options
   * @param options.foo
   * @param options.bar
   */
  constructor({ foo, bar }: { foo: string, bar: string }) {}
}

/**
 * @param {Error} error Exit code
 * @param {number} [code = 1] Exit code
 */
function quux (error, code = 1) {
};

/**
 * @param foo
 * @param bar
 */
function quux (foo) {

}
// Options: [{"allowExtraTrailingParamDocs":true}]

/**
 * @param cfg
 * @param cfg.foo
 * @param baz
 */
function quux ({foo}, baz) {

}

/**
 * @param options
 * @param options.foo
 */
function quux ({foo, ...extra}) {
}

/**
 * @param foo
 * @param bar
 */
function quux (foo, bar, ...extra) {

}

/**
* Converts an SVGRect into an object.
* @param {SVGRect} bbox - a SVGRect
*/
const bboxToObj = function ({x, y, width, height}) {
  return {x, y, width, height};
};

/**
* Converts an SVGRect into an object.
* @param {SVGRect} bbox - a SVGRect
*/
const bboxToObj = function ({x, y, width, height}) {
  return {x, y, width, height};
};

/**
* Converts an SVGRect into an object.
* @param {object} bbox - a SVGRect
*/
const bboxToObj = function ({x, y, width, height}) {
  return {x, y, width, height};
};
// Options: [{"checkTypesPattern":"SVGRect"}]

class CSS {
  /**
   * Set one or more CSS properties for the set of matched elements.
   *
   * @param {Object} propertyObject - An object of property-value pairs to set.
   */
  setCssObject(propertyObject: {[key: string]: string | number}): void {
  }
}

check-property-names

Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.

Options

enableFixer

Set to true to auto-remove @property duplicates (based on identical names).

Note that this option will remove duplicates of the same name even if the definitions do not match in other ways (e.g., the second property will be removed even if it has a different type or description).

Context Everywhere
Options enableFixer
Tags property

The following patterns are considered problems:

/**
 * @typedef (SomeType) SomeTypedef
 * @property Foo.Bar
 */
// Message: @property path declaration ("Foo.Bar") appears before any real property.

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 * @property Foo.Bar
 */
// Message: @property path declaration ("Foo.Bar") root node name ("Foo") does not match previous real property name ("foo").

/**
 * Assign the project to a list of employees.
 * @typedef (SomeType) SomeTypedef
 * @property {string} employees[].name - The name of an employee.
 * @property {string} employees[].department - The employee's department.
 */
// Message: @property path declaration ("employees[].name") appears before any real property.

/**
 * Assign the project to a list of employees.
 * @typedef (SomeType) SomeTypedef
 * @property {string} employees[].name - The name of an employee.
 * @property {string} employees[].name - The employee's department.
 */
// Options: [{"enableFixer":true}]
// Message: Duplicate @property "employees[].name"

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 * @property foo
 */
// Options: [{"enableFixer":true}]
// Message: Duplicate @property "foo"

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 * @property foo
 */
// Message: Duplicate @property "foo"

/**
 * @typedef (SomeType) SomeTypedef
 * @property cfg
 * @property cfg.foo
 * @property cfg.foo
 */
function quux ({foo, bar}) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @property "cfg.foo"

class Test {
    /**
     * @typedef (SomeType) SomeTypedef
     * @property cfg
     * @property cfg.foo
     * @property cfg.foo
     */
    quux ({foo, bar}) {

    }
}
// Options: [{"enableFixer":true}]
// Message: Duplicate @property "cfg.foo"

/**
 * @typedef (SomeType) SomeTypedef
 * @property cfg
 * @property cfg.foo
 * @property [cfg.foo]
 * @property baz
 */
function quux ({foo, bar}, baz) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @property "cfg.foo"

/**
 * @typedef (SomeType) SomeTypedef
 * @property cfg
 * @property cfg.foo
 * @property [cfg.foo="with a default"]
 * @property baz
 */
function quux ({foo, bar}, baz) {

}
// Options: [{"enableFixer":true}]
// Message: Duplicate @property "cfg.foo"

/**
 * @typedef (SomeType) SomeTypedef
 * @prop foo
 * @prop foo
 */
// Settings: {"jsdoc":{"tagNamePreference":{"property":"prop"}}}
// Options: [{"enableFixer":true}]
// Message: Duplicate @prop "foo"

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 */
// Settings: {"jsdoc":{"tagNamePreference":{"property":false}}}
// Message: Unexpected tag `@property`

The following patterns are not considered problems:

/**
 *
 */

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 */

/**
 * @typedef (SomeType) SomeTypedef
 * @prop foo
 */

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 * @property bar
 */

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 * @property foo.foo
 * @property bar
 */

/**
 * Assign the project to a list of employees.
 * @typedef (SomeType) SomeTypedef
 * @property {object[]} employees - The employees who are responsible for the project.
 * @property {string} employees[].name - The name of an employee.
 * @property {string} employees[].department - The employee's department.
 */

/**
 * @typedef (SomeType) SomeTypedef
 * @property {Error} error Exit code
 * @property {number} [code = 1] Exit code
 */

/**
 * @namespace (SomeType) SomeNamespace
 * @property {Error} error Exit code
 * @property {number} [code = 1] Exit code
 */

/**
 * @class
 * @property {Error} error Exit code
 * @property {number} [code = 1] Exit code
 */
function quux (code = 1) {
  this.error = new Error('oops');
  this.code = code;
}

/**
 * @typedef (SomeType) SomeTypedef
 * @property foo
 * @property foo.bar
 * @property foo.baz
 * @property bar
 */

check-syntax

Reports against Google Closure Compiler syntax.

Context everywhere
Tags N/A

The following patterns are considered problems:

/**
 * @param {string=} foo
 */
function quux (foo) {

}
// Message: Syntax should not be Google Closure Compiler style.

The following patterns are not considered problems:

/**
 * @param {string} [foo]
 */
function quux (foo) {

}

/**
 *
 */
function quux (foo) {

}

check-tag-names

Reports invalid block tag names.

Valid JSDoc 3 Block Tags are:

abstract
access
alias
async
augments
author
borrows
callback
class
classdesc
constant
constructs
copyright
default
deprecated
description
enum
event
example
exports
external
file
fires
function
generator
global
hideconstructor
ignore
implements
inheritdoc
inner
instance
interface
kind
lends
license
listens
member
memberof
memberof!
mixes
mixin
module
name
namespace
override
package
param
private
property
protected
public
readonly
requires
returns
see
since
static
summary
this
throws
todo
tutorial
type
typedef
variation
version
yields

modifies is also supported (see source) but is undocumented.

The following synonyms are also recognized if you set them in tagNamePreference as a key (or replacement):

arg
argument
const
constructor
defaultvalue
desc
emits
exception
extends
fileoverview
func
host
method
overview
prop
return
var
virtual
yield

If you wish to allow in certain cases both a primary tag name and its alias(es), you can set a normally non-preferred tag name to itself to indicate that you want to allow both the default tag (in this case @returns) and a non-default (in this case return):

"tagNamePreference": {
    "return": "return",
}

Because the tags indicated as replacements in settings.jsdoc.tagNamePreference will automatically be considered as valid, the above works.

For TypeScript (or Closure), when settings.jsdoc.mode is set to typescript or closure, one may also use the following:

template

And for Closure, when settings.jsdoc.mode is set to closure, one may use the following (in addition to the jsdoc and TypeScript tags):

define (synonym of `const` per jsdoc source)
dict
export
externs
final
implicitCast (casing distinct from that recognized by jsdoc internally)
inheritDoc (casing distinct from that recognized by jsdoc internally)
noalias
nocollapse
nocompile
noinline
nosideeffects
polymer
polymerBehavior
preserve
record (synonym of `interface` per jsdoc source)
struct
suppress
unrestricted

...and these undocumented tags which are only in source:

Current Tags

  • 25.4.3                                ...           latest (2 days ago)

258 Versions

  • 25.4.3                                ...           2 days ago
  • 25.4.2                                ...           10 days ago
  • 25.4.1                                ...           14 days ago
  • 25.4.0                                ...           15 days ago
  • 25.3.1                                ...           15 days ago
  • 25.3.0                                ...           15 days ago
  • 25.2.1                                ...           16 days ago
  • 25.2.0                                ...           17 days ago
  • 25.1.0                                ...           17 days ago
  • 25.0.1                                ...           19 days ago
  • 25.0.0                                ...           19 days ago
  • 24.0.6                                ...           22 days ago
  • 24.0.5                                ...           22 days ago
  • 24.0.4                                ...           22 days ago
  • 24.0.3                                ...           22 days ago
  • 24.0.2                                ...           25 days ago
  • 24.0.1                                ...           25 days ago
  • 24.0.0                                ...           a month ago
  • 23.1.0                                ...           a month ago
  • 23.0.1                                ...           a month ago
  • 23.0.0                                ...           2 months ago
  • 22.2.0                                ...           2 months ago
  • 22.1.0                                ...           2 months ago
  • 22.0.1                                ...           3 months ago
  • 22.0.0                                ...           3 months ago
  • 21.0.0                                ...           4 months ago
  • 20.4.0                                ...           4 months ago
  • 20.3.1                                ...           4 months ago
  • 20.3.0                                ...           5 months ago
  • 20.2.0                                ...           5 months ago
  • 20.1.0                                ...           5 months ago
  • 20.0.5                                ...           5 months ago
  • 20.0.4                                ...           5 months ago
  • 20.0.3                                ...           5 months ago
  • 20.0.2                                ...           5 months ago
  • 20.0.1                                ...           5 months ago
  • 20.0.0                                ...           5 months ago
  • 19.2.0                                ...           5 months ago
  • 19.1.0                                ...           5 months ago
  • 19.0.1                                ...           5 months ago
  • 19.0.0                                ...           5 months ago
  • 18.11.0                                ...           5 months ago
  • 18.10.0                                ...           5 months ago
  • 18.9.0                                ...           5 months ago
  • 18.8.0                                ...           5 months ago
  • 18.7.0                                ...           5 months ago
  • 18.6.2                                ...           5 months ago
  • 18.6.1                                ...           5 months ago
  • 18.6.0                                ...           5 months ago
  • 18.5.0                                ...           5 months ago
  • 18.4.4                                ...           5 months ago
  • 18.4.3                                ...           6 months ago
  • 18.4.2                                ...           6 months ago
  • 18.4.1                                ...           6 months ago
  • 18.4.0                                ...           6 months ago
  • 18.3.0                                ...           6 months ago
  • 18.2.2                                ...           6 months ago
  • 18.2.1                                ...           6 months ago
  • 18.2.0                                ...           6 months ago
  • 18.1.6                                ...           6 months ago
  • 18.1.5                                ...           6 months ago
  • 18.1.4                                ...           6 months ago
  • 18.1.3                                ...           6 months ago
  • 18.1.2                                ...           6 months ago
  • 18.1.1                                ...           6 months ago
  • 18.1.0                                ...           6 months ago
  • 18.0.1                                ...           6 months ago
  • 18.0.0                                ...           7 months ago
  • 17.1.2                                ...           7 months ago
  • 17.1.1                                ...           7 months ago
  • 17.1.0                                ...           7 months ago
  • 17.0.1                                ...           7 months ago
  • 17.0.0                                ...           7 months ago
  • 16.1.1                                ...           7 months ago
  • 16.1.0                                ...           7 months ago
  • 16.0.0                                ...           7 months ago
  • 15.12.2                                ...           7 months ago
  • 15.12.1                                ...           7 months ago
  • 15.12.0                                ...           7 months ago
  • 15.11.1                                ...           7 months ago
  • 15.11.0                                ...           8 months ago
  • 15.10.1                                ...           8 months ago
  • 15.10.0                                ...           8 months ago
  • 15.9.10                                ...           8 months ago
  • 15.9.9                                ...           8 months ago
  • 15.9.8                                ...           8 months ago
  • 15.9.7                                ...           8 months ago
  • 15.9.6                                ...           8 months ago
  • 15.9.5                                ...           8 months ago
  • 15.9.4                                ...           8 months ago
  • 15.9.3                                ...           8 months ago
  • 15.9.2                                ...           8 months ago
  • 15.9.1                                ...           9 months ago
  • 15.9.0                                ...           9 months ago
  • 15.8.4                                ...           9 months ago
  • 15.8.3                                ...           9 months ago
  • 15.8.2                                ...           9 months ago
  • 15.8.1                                ...           9 months ago
  • 15.8.0                                ...           10 months ago
  • 15.7.2                                ...           10 months ago
  • 15.7.1                                ...           10 months ago
  • 15.7.0                                ...           10 months ago
  • 15.6.2                                ...           10 months ago
  • 15.6.1                                ...           10 months ago
  • 15.6.0                                ...           10 months ago
  • 15.5.6                                ...           10 months ago
  • 15.5.5                                ...           10 months ago
  • 15.5.4                                ...           10 months ago
  • 15.5.3                                ...           10 months ago
  • 15.5.2                                ...           10 months ago
  • 15.5.1                                ...           10 months ago
  • 15.5.0                                ...           10 months ago
  • 15.4.2                                ...           10 months ago
  • 15.4.1                                ...           10 months ago
  • 15.4.0                                ...           10 months ago
  • 15.3.9                                ...           a year ago
  • 15.3.8                                ...           a year ago
  • 15.3.7                                ...           a year ago
  • 15.3.6                                ...           a year ago
  • 15.3.5                                ...           a year ago
  • 15.3.4                                ...           a year ago
  • 15.3.3                                ...           a year ago
  • 15.3.2                                ...           a year ago
  • 15.3.1                                ...           a year ago
  • 15.3.0                                ...           a year ago
  • 15.2.0                                ...           a year ago
  • 15.1.0                                ...           a year ago
  • 15.0.1                                ...           a year ago
  • 15.0.0                                ...           a year ago
  • 14.1.0                                ...           a year ago
  • 14.0.0                                ...           a year ago
  • 13.0.0                                ...           a year ago
  • 12.0.0                                ...           a year ago
  • 11.2.1                                ...           a year ago
  • 11.2.0                                ...           a year ago
  • 11.1.0                                ...           a year ago
  • 11.0.0                                ...           a year ago
  • 10.3.0                                ...           a year ago
  • 10.2.0                                ...           a year ago
  • 10.1.1                                ...           a year ago
  • 10.1.0                                ...           a year ago
  • 10.0.3                                ...           a year ago
  • 10.0.2                                ...           a year ago
  • 10.0.1                                ...           a year ago
  • 10.0.0                                ...           a year ago
  • 9.1.0                                ...           a year ago
  • 9.0.1                                ...           a year ago
  • 9.0.0                                ...           a year ago
  • 8.7.0                                ...           a year ago
  • 8.6.2                                ...           a year ago
  • 8.6.1                                ...           a year ago
  • 8.6.0                                ...           a year ago
  • 8.5.1                                ...           a year ago
  • 8.5.0                                ...           a year ago
  • 8.4.6                                ...           a year ago
  • 8.4.5                                ...           a year ago
  • 8.4.4                                ...           a year ago
  • 8.4.3                                ...           a year ago
  • 8.4.2                                ...           a year ago
  • 8.4.1                                ...           a year ago
  • 8.4.0                                ...           a year ago
  • 8.3.2                                ...           a year ago
  • 8.3.1                                ...           a year ago
  • 8.3.0                                ...           a year ago
  • 8.2.0                                ...           a year ago
  • 8.1.0                                ...           a year ago
  • 8.0.2                                ...           a year ago
  • 8.0.1                                ...           a year ago
  • 8.0.0                                ...           a year ago
  • 7.2.3                                ...           a year ago
  • 7.2.2                                ...           a year ago
  • 7.2.1                                ...           a year ago
  • 7.2.0                                ...           a year ago
  • 7.1.0                                ...           a year ago
  • 7.0.2                                ...           a year ago
  • 7.0.1                                ...           a year ago
  • 7.0.0                                ...           a year ago
  • 6.0.3                                ...           a year ago
  • 6.0.2                                ...           a year ago
  • 6.0.1                                ...           a year ago
  • 6.0.0                                ...           a year ago
  • 5.0.2                                ...           a year ago
  • 5.0.1                                ...           a year ago
  • 5.0.0                                ...           a year ago
  • 4.8.4                                ...           a year ago
  • 4.8.3                                ...           a year ago
  • 4.8.2                                ...           a year ago
  • 4.8.1                                ...           a year ago
  • 4.8.0                                ...           a year ago
  • 4.7.0                                ...           a year ago
  • 4.6.0                                ...           a year ago
  • 4.5.0                                ...           a year ago
  • 4.4.3                                ...           a year ago
  • 4.4.2                                ...           a year ago
  • 4.4.1                                ...           a year ago
  • 4.4.0                                ...           a year ago
  • 4.3.0                                ...           a year ago
  • 4.2.0                                ...           a year ago
  • 4.1.1                                ...           a year ago
  • 4.1.0                                ...           a year ago
  • 4.0.1                                ...           a year ago
  • 4.0.0                                ...           a year ago
  • 3.15.1                                ...           a year ago
  • 3.15.0                                ...           a year ago
  • 3.14.1                                ...           a year ago
  • 3.14.0                                ...           a year ago
  • 3.13.0                                ...           a year ago
  • 3.12.1                                ...           a year ago
  • 3.12.0                                ...           a year ago
  • 3.11.0                                ...           a year ago
  • 3.10.0                                ...           a year ago
  • 3.9.1                                ...           2 years ago
  • 3.9.0                                ...           2 years ago
  • 3.8.0                                ...           2 years ago
  • 3.7.2                                ...           2 years ago
  • 3.7.1                                ...           2 years ago
  • 3.7.0                                ...           2 years ago
  • 3.6.3                                ...           2 years ago
  • 3.6.2                                ...           2 years ago
  • 3.6.1                                ...           2 years ago
  • 3.6.0                                ...           2 years ago
  • 3.5.0                                ...           2 years ago
  • 3.4.1                                ...           2 years ago
  • 3.4.0                                ...           2 years ago
  • 3.3.1                                ...           2 years ago
  • 3.3.0                                ...           2 years ago
  • 3.2.0                                ...           3 years ago
  • 3.1.3                                ...           3 years ago
  • 3.1.2                                ...           3 years ago
  • 3.1.1                                ...           3 years ago
  • 3.1.0                                ...           3 years ago
  • 3.0.2                                ...           3 years ago
  • 3.0.1                                ...           3 years ago
  • 3.0.0                                ...           3 years ago
  • 2.4.0                                ...           4 years ago
  • 2.3.1                                ...           4 years ago
  • 2.3.0                                ...           4 years ago
  • 2.2.4                                ...           4 years ago
  • 2.2.3                                ...           4 years ago
  • 2.2.2                                ...           4 years ago
  • 2.2.1                                ...           4 years ago
  • 2.2.0                                ...           4 years ago
  • 2.1.4                                ...           4 years ago
  • 2.1.3                                ...           4 years ago
  • 2.1.2                                ...           4 years ago
  • 2.1.1                                ...           4 years ago
  • 2.1.0                                ...           4 years ago
  • 2.0.4                                ...           4 years ago
  • 2.0.3                                ...           4 years ago
  • 2.0.2                                ...           4 years ago
  • 2.0.1                                ...           4 years ago
  • 1.1.3                                ...           4 years ago
  • 1.1.2                                ...           4 years ago
  • 1.1.0                                ...           5 years ago
  • 1.0.1                                ...           5 years ago
  • 0.0.2                                ...           5 years ago
  • 0.0.1                                ...           5 years ago
  • 0.0.0                                ...           5 years ago
Maintainers (1)
Downloads
Today 2,003
This Week 5,491
This Month 29,176
Last Day 1,382
Last Week 6,151
Last Month 27,708
Dependencies (7)
Dev Dependencies (20)
Dependents (289)

Copyright 2014 - 2016 © taobao.org |