Skip to content

Latest commit

 

History

History
455 lines (356 loc) · 8.62 KB

File metadata and controls

455 lines (356 loc) · 8.62 KB

informative-docs

Reports on JSDoc texts that serve only to restate their attached name.

Devs sometimes write JSDoc descriptions that add no additional information just to fill out the doc:

/** The user id. */
let userId;

Those "uninformative" docs comments take up space without being helpful. This rule requires all docs comments contain at least one word not already in the code.

Options

A single options object has the following properties.

aliases

The aliases option allows indicating words as synonyms (aliases) of each other.

For example, with { aliases: { emoji: ["smiley", "winkey"] } }, the following comment would be considered uninformative:

/** A smiley/winkey. */
let emoji;

The default aliases option is:

{
  "a": ["an", "our"]
}

excludedTags

Tags that should not be checked for valid contents.

For example, with { excludedTags: ["category"] }, the following comment would not be considered uninformative:

/** @category Types */
function computeTypes(node) {
  // ...
}

No tags are excluded by default.

uselessWords

Words that are ignored when searching for one that adds meaning.

For example, with { uselessWords: ["our"] }, the following comment would be considered uninformative:

/** Our text. */
let text;

The default uselessWords option is:

["a", "an", "i", "in", "of", "s", "the"]

Context and settings

Context everywhere
Tags any
Recommended false
Settings
Options aliases, excludedTags, uselessWords

Failing examples

The following patterns are considered problems:

/** the  */
let myValue = 3;
// Message: This description only repeats the name it describes.

/** The user id. */
let userId: string;
// Message: This description only repeats the name it describes.

/** the my value */
let myValue = 3;
// Message: This description only repeats the name it describes.

/** value **/
let myValue,
  count = 3;
// Message: This description only repeats the name it describes.

let myValue,
  /** count **/
  count = 3;
// Message: This description only repeats the name it describes.

/**
 * the foo.
 */
function foo() {}
// Message: This description only repeats the name it describes.

/**
 * the value foo.
 */
const value = function foo() {}
// Message: This description only repeats the name it describes.

const value = {
  /**
   * the  prop.
   */
  prop: true,
}
// Message: This description only repeats the name it describes.

/**
 * name
 */
class Name {}
// Message: This description only repeats the name it describes.

/**
 * abc def
 */
const abc = class Def {}
// Message: This description only repeats the name it describes.

class Abc {
  /** the abc def! */
  def;
}
// Message: This description only repeats the name it describes.

const _ = class Abc {
  /** the abc def! */
  def;
}
// Message: This description only repeats the name it describes.

class Abc {
  /** the abc def! */
  def() {};
}
// Message: This description only repeats the name it describes.

class Abc {
  /** def */
  accessor def;
}
// Message: This description only repeats the name it describes.

class Abc {
  /** def */
  def() {}
}
// Message: This description only repeats the name it describes.

class Abc {
  /** def */
  abstract accessor def;
}
// Message: This description only repeats the name it describes.

class Abc {
  /** def */
  abstract def();
}
// Message: This description only repeats the name it describes.

class Abc {
  /** def */
  abstract def;
}
// Message: This description only repeats the name it describes.

/** abc */
namespace Abc {}
// Message: This description only repeats the name it describes.

class Abc {
  /** def */
  def();
  def() {}
}
// Message: This description only repeats the name it describes.

/** abc */
declare function abc();
// Message: This description only repeats the name it describes.

/** abc */
enum Abc {}
// Message: This description only repeats the name it describes.

enum Abc {
  /** def */
  def,
}
// Message: This description only repeats the name it describes.

/** def */
interface Def {}
// Message: This description only repeats the name it describes.

/** def */
type Def = {};
// Message: This description only repeats the name it describes.

/**
 * count
 *
 * @description the value
 */
let value = 3;
// Message: This tag description only repeats the name it describes.

/** @param {number} param - the param */
function takesOne(param) {}
// Message: This tag description only repeats the name it describes.

/** @other param - takes one */
function takesOne(param) {}
// Message: This tag description only repeats the name it describes.

/**
 * takes one
 * @other param - takes one
 */
function takesOne(param) {}
// Message: This description only repeats the name it describes.

/**
 * - takes one
 * @other param - takes one
 */
function takesOne(param) {}
// Message: This description only repeats the name it describes.

/** A smiley/winkey. */
let emoji;
// "jsdoc/informative-docs": ["error"|"warn", {"aliases":{"emoji":["smiley","winkey"]}}]
// Message: This description only repeats the name it describes.

/**
 * package name from path
 */
export function packageNameFromPath(path) {
  const base = basename(path);
  return /^v\d+(\.\d+)?$/.exec(base) || /^ts\d\.\d/.exec(base) ? basename(dirname(path)) : base;
}
// Message: This description only repeats the name it describes.

/**
 * package name from path
 */
export default function packageNameFromPath(path) {
  const base = basename(path);
  return /^v\d+(\.\d+)?$/.exec(base) || /^ts\d\.\d/.exec(base) ? basename(dirname(path)) : base;
}
// Message: This description only repeats the name it describes.

Passing examples

The following patterns are not considered problems:

/**   */
let myValue = 3;

/** count */
let myValue = 3;

/** Informative info user id. */
let userId: string;

let myValue,
  /** count value **/
  count = 3;

/**
 * Does X Y Z work.
 */
function foo() {}

const value = {
  /**
   * the truthiness of the prop.
   */
  prop: true,
}

const value = {
  /**
   * the truthiness of the prop.
   */
  ['prop']: true,
}

/**
 * abc def ghi
 */
const abc = function def() {}

/**
 * name extra
 */
class Name {}

/**
 * abc name extra
 */
const abc = class Name {}

class Abc {
  /** ghi */
  def;
}

class Abc {
  /** ghi */
  accessor def;
}

class Abc {
  /** ghi */
  def() {}
}

class Abc {
  /** ghi */
  abstract accessor def;
}

class Abc {
  /** ghi */
  abstract def();
}

class Abc {
  /** ghi */
  abstract def;
}

/** abc */
namespace Def {}

class Abc {
  /** ghi */
  def();
  def() {}
}

/** abc */
declare function def();

/** abc */
enum Def {}

enum Abc {
  /** def */
  ghi,
}

/** abc */
interface Def {}

/** abc */
type Def = {};

/** abc */
type Def = {};

/**
 * count
 *
 * @description increment value
 */
let value = 3;

/**
 * count
 *
 * @unknownTag - increment value
 */
let value = 3;

/**
 * @other param - takes one two
 */
function takesOne(param) {}

/**
 * takes abc param
 */
function takesOne(param) {}

/**
 * @class
 *
 * @param {number} value - Some useful text
 */
function MyAmazingThing(value) {}

/**
 * My option.
 * @default {}
 */
// "jsdoc/informative-docs": ["error"|"warn", {"excludedTags":["default"]}]

/**
 * The
 */
// "jsdoc/informative-docs": ["error"|"warn", {"uselessWords":["an"]}]