# require-yields * [Options](#user-content-require-yields-options) * [`contexts`](#user-content-require-yields-options-contexts) * [`exemptedBy`](#user-content-require-yields-options-exemptedby) * [`forceRequireNext`](#user-content-require-yields-options-forcerequirenext) * [`forceRequireYields`](#user-content-require-yields-options-forcerequireyields) * [`next`](#user-content-require-yields-options-next) * [`nextWithGeneratorTag`](#user-content-require-yields-options-nextwithgeneratortag) * [`withGeneratorTag`](#user-content-require-yields-options-withgeneratortag) * [Context and settings](#user-content-require-yields-context-and-settings) * [Failing examples](#user-content-require-yields-failing-examples) * [Passing examples](#user-content-require-yields-passing-examples) Requires that yields are documented. Will also report if multiple `@yields` tags are present. See the `next`, `forceRequireNext`, and `nextWithGeneratorTag` options for an option to expect a non-standard `@next` tag. ## Options A single options object has the following properties. ### contexts Set this to an array of strings representing the AST context (or objects with optional `context` and `comment` properties) where you wish the rule to be applied. `context` defaults to `any` and `comment` defaults to no specific comment context. Overrides the default contexts (`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`). Set to `"any"` if you want the rule to apply to any JSDoc block throughout your files (as is necessary for finding function blocks not attached to a function declaration or expression, i.e., `@callback` or `@function` (or its aliases `@func` or `@method`) (including those associated with an `@interface`). This rule will only apply on non-default contexts when there is such a tag present and the `forceRequireYields` option is set or if the `withGeneratorTag` option is set with a present `@generator` tag (since we are not checking against the actual `yield` values in these cases). ### exemptedBy Array of tags (e.g., `['type']`) whose presence on the document block avoids the need for a `@yields`. Defaults to an array with `inheritdoc`. If you set this array, it will overwrite the default, so be sure to add back `inheritdoc` if you wish its presence to cause exemption of the rule. ### forceRequireNext Set to `true` to always insist on `@next` documentation even if there are no `yield` statements in the function or none return values. May be desired to flag that a project is aware of the expected yield return being `undefined`. Defaults to `false`. ### forceRequireYields Set to `true` to always insist on `@yields` documentation for generators even if there are only expressionless `yield` statements in the function. May be desired to flag that a project is aware of an `undefined`/`void` yield. Defaults to `false`. ### next If `true`, this option will insist that any use of a `yield` return value (e.g., `const rv = yield;` or `const rv = yield value;`) has a (non-standard) `@next` tag (in addition to any `@yields` tag) so as to be able to document the type expected to be supplied into the iterator (the `Generator` iterator that is returned by the call to the generator function) to the iterator (e.g., `it.next(value)`). The tag will not be expected if the generator function body merely has plain `yield;` or `yield value;` statements without returning the values. Defaults to `false`. ### nextWithGeneratorTag If a `@generator` tag is present on a block, require (non-standard ) `@next` (see `next` option). This will require using `void` or `undefined` in cases where generators do not use the `next()`-supplied incoming `yield`-returned value. Defaults to `false`. See `contexts` to `any` if you want to catch `@generator` with `@callback` or such not attached to a function. ### withGeneratorTag If a `@generator` tag is present on a block, require `@yields`/`@yield`. Defaults to `true`. See `contexts` to `any` if you want to catch `@generator` with `@callback` or such not attached to a function. ## Context and settings ||| |---|---| |Context|Generator functions (`FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled)| |Tags|`yields`| |Aliases|`yield`| |Recommended|true| | Options |`contexts`, `exemptedBy`, `forceRequireNext`, `forceRequireYields`, `next`, `nextWithGeneratorTag`, `withGeneratorTag`| | Settings | `ignoreReplacesDocs`, `overrideReplacesDocs`, `augmentsExtendsReplacesDocs`, `implementsReplacesDocs` | ## Failing examples The following patterns are considered problems: ````ts /** * */ function * quux (foo) { yield foo; } // Message: Missing JSDoc @yields declaration. /** * @yields */ function * quux (foo) { const retVal = yield foo; } // "jsdoc/require-yields": ["error"|"warn", {"next":true}] // Message: Missing JSDoc @next declaration. /** * @yields */ function * quux (foo) { const retVal = yield; } // "jsdoc/require-yields": ["error"|"warn", {"next":true}] // Message: Missing JSDoc @next declaration. /** * @yields {void} */ function * quux () { } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireNext":true}] // Message: Missing JSDoc @next declaration. /** * @yields {void} */ function * quux () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireNext":true}] // Message: Missing JSDoc @next declaration. /** * */ function * quux (foo) { const a = yield foo; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux (foo) { yield foo; } // Settings: {"jsdoc":{"tagNamePreference":{"yields":"yield"}}} // Message: Missing JSDoc @yield declaration. /** * @yields */ function * quux (foo) { const val = yield foo; } // Settings: {"jsdoc":{"tagNamePreference":{"next":"yield-returns"}}} // "jsdoc/require-yields": ["error"|"warn", {"next":true}] // Message: Missing JSDoc @yield-returns declaration. /** * @yields * @next */ function * quux () { const ret = yield 5; } // Settings: {"jsdoc":{"tagNamePreference":{"next":false}}} // "jsdoc/require-yields": ["error"|"warn", {"next":true}] // Message: Unexpected tag `@next` /** * */ function * quux() { yield 5; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * */ function * quux() { yield; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * */ const quux = async function * () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * */ async function * quux () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * @function * @generator */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * @callback * @generator */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * @yields {undefined} * @yields {void} */ function * quux (foo) { return foo; } // Message: Found more than one @yields declaration. /** * @yields */ function * quux () { } // Settings: {"jsdoc":{"tagNamePreference":{"yields":false}}} // Message: Unexpected tag `@yields` /** * @param foo */ function * quux (foo) { yield 'bar'; } // "jsdoc/require-yields": ["error"|"warn", {"exemptedBy":["notPresent"]}] // Message: Missing JSDoc @yields declaration. /** * @param {array} a */ async function * foo(a) { return; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * @param {array} a */ async function * foo(a) { yield Promise.all(a); } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. class quux { /** * */ * quux () { yield; } } // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"forceRequireYields":true}] // Message: Missing JSDoc @yields declaration. /** * @param {array} a */ async function * foo(a) { yield Promise.all(a); } // Message: Missing JSDoc @yields declaration. /** * @generator */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"withGeneratorTag":true}] // Message: Missing JSDoc @yields declaration. /** * @generator * @yields */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"nextWithGeneratorTag":true}] // Message: Missing JSDoc @next declaration. /** * */ function * quux () { if (true) { yield; } yield true; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { try { yield true; } catch (err) { } yield; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { try { } finally { yield true; } yield; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { try { yield; } catch (err) { } yield true; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { try { something(); } catch (err) { yield true; } yield; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { switch (true) { case 'abc': yield true; } yield; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { switch (true) { case 'abc': yield; } yield true; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { for (const i of abc) { yield true; } yield; } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { for (const a in b) { yield true; } } // Message: Missing JSDoc @yields declaration. /** * */ function * quux () { for (let i=0; i ## Passing examples The following patterns are not considered problems: ````ts /** * @yields Foo. */ function * quux () { yield foo; } /** * @yields Foo. */ function * quux () { yield foo; } // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"]}] /** * */ function * quux () { } /** * */ function * quux () { yield; } /** * */ function quux (bar) { bar.doSomething(function * (baz) { yield baz.corge(); }) } /** * @yields {Array} */ function * quux (bar) { yield bar.doSomething(function * (baz) { yield baz.corge(); }) } /** * @inheritdoc */ function * quux (foo) { } /** * @override */ function * quux (foo) { } /** * @constructor */ function * quux (foo) { } /** * @implements */ function * quux (foo) { yield; } /** * @override */ function * quux (foo) { yield foo; } /** * @class */ function * quux (foo) { yield foo; } /** * @yields {object} */ function * quux () { yield {a: foo}; } /** * @yields {void} */ function * quux () { } /** * @yields {undefined} */ function * quux () { } /** * @yields {void} */ function quux () { } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** * @yields {void} * @next {void} */ function * quux () { } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireNext":true}] /** * @yields {void} */ function * quux () { yield undefined; } /** * @yields {void} */ function * quux () { yield undefined; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** * @yields {void} */ function * quux () { yield; } /** * @yields {void} */ function * quux () { } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** * @yields {void} */ function * quux () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** @type {SpecialIterator} */ function * quux () { yield 5; } /** * @yields {Something} */ async function * quux () { } // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** * */ async function * quux () {} /** * */ const quux = async function * () {} /** * @type {MyCallback} */ function * quux () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"exemptedBy":["type"]}] /** * @param {array} a */ async function * foo (a) { yield; } /** * */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"]}] /** * @function */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"]}] /** * @function */ // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** * @callback */ // "jsdoc/require-yields": ["error"|"warn", {"forceRequireYields":true}] /** * @generator */ // "jsdoc/require-yields": ["error"|"warn", {"withGeneratorTag":true}] /** * @generator */ // "jsdoc/require-yields": ["error"|"warn", {"nextWithGeneratorTag":true}] /** * @generator * @yields */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"withGeneratorTag":true}] /** * @generator * @yields * @next */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"nextWithGeneratorTag":true}] /** * @generator */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"withGeneratorTag":false}] /** * @generator * @yields */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"nextWithGeneratorTag":false}] /** * @yields */ function * quux (foo) { const a = yield foo; } /** * @yields * @next */ function * quux (foo) { let a = yield; } // "jsdoc/require-yields": ["error"|"warn", {"next":true}] /** * @yields * @next */ function * quux (foo) { const a = yield foo; } // "jsdoc/require-yields": ["error"|"warn", {"next":true}] /** * */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"nextWithGeneratorTag":true}] /** * */ // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"next":true}] /** * */ function quux () {} // "jsdoc/require-yields": ["error"|"warn", {"contexts":["any"],"next":true}] /** * @yields {void} */ function * quux () { yield; } // "jsdoc/require-yields": ["error"|"warn", {"next":true}] /** * */ function * quux (foo) { const a = function * bar () { yield foo; } } /** * */ export { foo } from "bar" // "jsdoc/require-yields": ["error"|"warn", {"contexts":["ExportNamedDeclaration"]}] ````