Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .README/rules/require-param.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,15 @@ supplied as default values. Defaults to `false`.
Set to `true` to ignore reporting when all params are missing. Defaults to
`false`.

### `interfaceExemptsParamsCheck`

Set if you wish TypeScript interfaces to exempt checks for the existence of
`@param`'s.

Will check for a type defining the function itself (on a variable
declaration) or if there is a single destructured object with a type.
Defaults to `false`.

## Context and settings

| | |
Expand All @@ -382,7 +391,7 @@ Set to `true` to ignore reporting when all params are missing. Defaults to
| Tags | `param` |
| Aliases | `arg`, `argument` |
|Recommended | true|
| Options |`autoIncrementBase`, `checkConstructors`, `checkDestructured`, `checkDestructuredRoots`, `checkGetters`, `checkRestProperty`, `checkSetters`, `checkTypesPattern`, `contexts`, `enableFixer`, `enableRestElementFixer`, `enableRootFixer`, `exemptedBy`, `ignoreWhenAllParamsMissing`, `unnamedRootBase`, `useDefaultObjectProperties`|
| Options |`autoIncrementBase`, `checkConstructors`, `checkDestructured`, `checkDestructuredRoots`, `checkGetters`, `checkRestProperty`, `checkSetters`, `checkTypesPattern`, `contexts`, `enableFixer`, `enableRestElementFixer`, `enableRootFixer`, `exemptedBy`, `ignoreWhenAllParamsMissing`, `interfaceExemptsParamsCheck`, `unnamedRootBase`, `useDefaultObjectProperties`|
| Settings | `ignoreReplacesDocs`, `overrideReplacesDocs`, `augmentsExtendsReplacesDocs`, `implementsReplacesDocs`|

## Failing examples
Expand Down
50 changes: 49 additions & 1 deletion docs/rules/require-param.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* [`checkDestructuredRoots`](#user-content-require-param-options-checkdestructuredroots)
* [`useDefaultObjectProperties`](#user-content-require-param-options-usedefaultobjectproperties)
* [`ignoreWhenAllParamsMissing`](#user-content-require-param-options-ignorewhenallparamsmissing)
* [`interfaceExemptsParamsCheck`](#user-content-require-param-options-interfaceexemptsparamscheck)
* [Context and settings](#user-content-require-param-context-and-settings)
* [Failing examples](#user-content-require-param-failing-examples)
* [Passing examples](#user-content-require-param-passing-examples)
Expand Down Expand Up @@ -445,6 +446,17 @@ supplied as default values. Defaults to `false`.
Set to `true` to ignore reporting when all params are missing. Defaults to
`false`.

<a name="user-content-require-param-options-interfaceexemptsparamscheck"></a>
<a name="require-param-options-interfaceexemptsparamscheck"></a>
### <code>interfaceExemptsParamsCheck</code>

Set if you wish TypeScript interfaces to exempt checks for the existence of
`@param`'s.

Will check for a type defining the function itself (on a variable
declaration) or if there is a single destructured object with a type.
Defaults to `false`.

<a name="user-content-require-param-context-and-settings"></a>
<a name="require-param-context-and-settings"></a>
## Context and settings
Expand All @@ -455,7 +467,7 @@ Set to `true` to ignore reporting when all params are missing. Defaults to
| Tags | `param` |
| Aliases | `arg`, `argument` |
|Recommended | true|
| Options |`autoIncrementBase`, `checkConstructors`, `checkDestructured`, `checkDestructuredRoots`, `checkGetters`, `checkRestProperty`, `checkSetters`, `checkTypesPattern`, `contexts`, `enableFixer`, `enableRestElementFixer`, `enableRootFixer`, `exemptedBy`, `ignoreWhenAllParamsMissing`, `unnamedRootBase`, `useDefaultObjectProperties`|
| Options |`autoIncrementBase`, `checkConstructors`, `checkDestructured`, `checkDestructuredRoots`, `checkGetters`, `checkRestProperty`, `checkSetters`, `checkTypesPattern`, `contexts`, `enableFixer`, `enableRestElementFixer`, `enableRootFixer`, `exemptedBy`, `ignoreWhenAllParamsMissing`, `interfaceExemptsParamsCheck`, `unnamedRootBase`, `useDefaultObjectProperties`|
| Settings | `ignoreReplacesDocs`, `overrideReplacesDocs`, `augmentsExtendsReplacesDocs`, `implementsReplacesDocs`|

<a name="user-content-require-param-failing-examples"></a>
Expand Down Expand Up @@ -1185,6 +1197,25 @@ function quux (a, b) {}
export type Test = (foo: number) => string;
// "jsdoc/require-param": ["error"|"warn", {"contexts":["TSFunctionType"]}]
// Message: Missing JSDoc @param "foo" declaration.

/**
*
*/
const quux = function quux (foo) {
};
// "jsdoc/require-param": ["error"|"warn", {"interfaceExemptsParamsCheck":true}]
// Message: Missing JSDoc @param "foo" declaration.

/**
*
*/
function quux ({
abc,
def
}) {
}
// "jsdoc/require-param": ["error"|"warn", {"interfaceExemptsParamsCheck":true}]
// Message: Missing JSDoc @param "root0" declaration.
````


Expand Down Expand Up @@ -1853,5 +1884,22 @@ function myFunction(foo: string): void;
*/
function myFunction(): void;
function myFunction(foo?: string) {}

/**
*
*/
const quux: FunctionInterface = function quux (foo) {
};
// "jsdoc/require-param": ["error"|"warn", {"interfaceExemptsParamsCheck":true}]

/**
*
*/
function quux ({
abc,
def
}: FunctionInterface) {
}
// "jsdoc/require-param": ["error"|"warn", {"interfaceExemptsParamsCheck":true}]
````

1 change: 1 addition & 0 deletions src/rules.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ export interface Rules {
enableRootFixer?: boolean;
exemptedBy?: string[];
ignoreWhenAllParamsMissing?: boolean;
interfaceExemptsParamsCheck?: boolean;
unnamedRootBase?: string[];
useDefaultObjectProperties?: boolean;
}
Expand Down
20 changes: 20 additions & 0 deletions src/rules/requireParam.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const rootNamer = (desiredRoots, currentIndex) => {
export default iterateJsdoc(({
context,
jsdoc,
node,
utils,
}) => {
/* eslint-enable complexity -- Temporary */
Expand All @@ -57,12 +58,28 @@ export default iterateJsdoc(({
enableRestElementFixer = true,
enableRootFixer = true,
ignoreWhenAllParamsMissing = false,
interfaceExemptsParamsCheck = false,
unnamedRootBase = [
'root',
],
useDefaultObjectProperties = false,
} = context.options[0] || {};

if (interfaceExemptsParamsCheck) {
if (node && 'params' in node && node.params.length === 1 &&
node.params?.[0] && typeof node.params[0] === 'object' &&
node.params[0].type === 'ObjectPattern' &&
'typeAnnotation' in node.params[0] && node.params[0].typeAnnotation
) {
return;
}

if (node && node.parent.type === 'VariableDeclarator' &&
'typeAnnotation' in node.parent.id && node.parent.id.typeAnnotation) {
return;
}
}

const preferredTagName = /** @type {string} */ (utils.getPreferredTagName({
tagName: 'param',
}));
Expand Down Expand Up @@ -579,6 +596,9 @@ export default iterateJsdoc(({
ignoreWhenAllParamsMissing: {
type: 'boolean',
},
interfaceExemptsParamsCheck: {
type: 'boolean',
},
unnamedRootBase: {
items: {
type: 'string',
Expand Down
121 changes: 121 additions & 0 deletions test/rules/assertions/requireParam.js
Original file line number Diff line number Diff line change
Expand Up @@ -2587,6 +2587,87 @@ export default /** @type {import('../index.js').TestCases} */ ({
export type Test = (foo: number) => string;
`,
},
{
code: `
/**
*
*/
const quux = function quux (foo) {
};
`,
errors: [
{
line: 2,
message: 'Missing JSDoc @param "foo" declaration.',
},
],
languageOptions: {
parser: typescriptEslintParser,
sourceType: 'module',
},
options: [
{
interfaceExemptsParamsCheck: true,
},
],
output: `
/**
*
* @param foo
*/
const quux = function quux (foo) {
};
`,
},

{
code: `
/**
*
*/
function quux ({
abc,
def
}) {
}
`,
errors: [
{
line: 2,
message: 'Missing JSDoc @param "root0" declaration.',
},
{
line: 2,
message: 'Missing JSDoc @param "root0.abc" declaration.',
},
{
line: 2,
message: 'Missing JSDoc @param "root0.def" declaration.',
},
],
languageOptions: {
parser: typescriptEslintParser,
sourceType: 'module',
},
options: [
{
interfaceExemptsParamsCheck: true,
},
],
output: `
/**
*
* @param root0
* @param root0.abc
* @param root0.def
*/
function quux ({
abc,
def
}) {
}
`,
},
],
valid: [
{
Expand Down Expand Up @@ -3695,5 +3776,45 @@ export default /** @type {import('../index.js').TestCases} */ ({
sourceType: 'module',
},
},
{
code: `
/**
*
*/
const quux: FunctionInterface = function quux (foo) {
};
`,
languageOptions: {
parser: typescriptEslintParser,
sourceType: 'module',
},
options: [
{
interfaceExemptsParamsCheck: true,
},
],
},

{
code: `
/**
*
*/
function quux ({
abc,
def
}: FunctionInterface) {
}
`,
languageOptions: {
parser: typescriptEslintParser,
sourceType: 'module',
},
options: [
{
interfaceExemptsParamsCheck: true,
},
],
},
],
});
Loading