Skip to content
Open
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
9 changes: 5 additions & 4 deletions packages/base/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Update `jsdoc/require-jsdoc` to loosen requirements for various kinds of symbols ([#433](https://github.com/MetaMask/eslint-config/pull/433))
- Instead of requiring JSDoc for all arrow functions and function expressions, require only arrow functions not contained within plain objects or are not arguments to functions or methods.

## [15.0.0]

### Changed
Expand All @@ -15,12 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- New things that now require documentation are:
- Arrow functions
- Class declarations
- TypeScript enum declarations
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's true that the base config did apparently require JSDoc for TypeScript symbols, that wasn't true in practice because the JSDoc plugin within the base config doesn't know about TypeScript.

- Function expressions
- TypeScript interface declarations
- Method definitions
- TypeScript type alias declarations
- TypeScript property signatures
- **BREAKING:** Convert various rules from `warn` to `error` ([#424](https://github.com/MetaMask/eslint-config/pull/424))
- The rules impacted are:
- `promise/no-callback-in-promise`
Expand Down
8 changes: 2 additions & 6 deletions packages/base/rules-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,13 @@
"error",
{
"require": {
"ArrowFunctionExpression": true,
"ClassDeclaration": true,
"FunctionDeclaration": true,
"FunctionExpression": true,
"MethodDefinition": true
},
"contexts": [
"TSInterfaceDeclaration",
"TSTypeAliasDeclaration",
"TSEnumDeclaration",
"TSPropertySignature"
":not(Property, NewExpression, CallExpression) > ArrowFunctionExpression",
":not(Property, NewExpression, CallExpression) > FunctionExpression"
]
}
],
Expand Down
15 changes: 9 additions & 6 deletions packages/base/src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -397,17 +397,20 @@ const rules = createConfig({
'error',
{
require: {
ArrowFunctionExpression: true,
// Classes
ClassDeclaration: true,
// Function declarations
FunctionDeclaration: true,
FunctionExpression: true,
// Methods
MethodDefinition: true,
},
contexts: [
'TSInterfaceDeclaration',
'TSTypeAliasDeclaration',
'TSEnumDeclaration',
'TSPropertySignature',
// Arrow functions that are not contained within plain objects or
// are not arguments to functions or methods
':not(Property, NewExpression, CallExpression) > ArrowFunctionExpression',
// Function expressions that are not contained within plain objects
// or are not arguments to functions or methods
':not(Property, NewExpression, CallExpression) > FunctionExpression',
],
},
],
Expand Down
17 changes: 17 additions & 0 deletions packages/typescript/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Update `jsdoc/require-jsdoc` to loosen requirements for various kinds of symbols ([#433](https://github.com/MetaMask/eslint-config/pull/433))
- Require JSDoc not for all arrow functions, but only those not contained within plain objects or are not arguments to functions or methods.
- Require JSDoc not for all interfaces or type aliases, but only those that do not appear in declare blocks (ambient declarations).
- Require JSDoc not for all object types in return types, but only those in "root" types.

## [15.0.0]

### Changed
Expand All @@ -17,6 +24,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **BREAKING:** Update type import specifier rules ([#381](https://github.com/MetaMask/eslint-config/pull/381))
- `@typescript-eslint/consistent-type-imports` has been replaced with `import-x/consistent-type-specifier-style`
- The rule now prefers "top-level" type imports over inline. e.g. `import type { a } from 'x'` over `import { type a } from 'x'`
- **BREAKING:** Update `jsdoc/require-jsdoc` to require documentation for more things ([#394](https://github.com/MetaMask/eslint-config/pull/394))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changelog entry was missing when 15.0.0 was released. This should list TypeScript symbols for which documentation is required (not the changelog for the base config).

- New things that now require documentation are:
- Arrow functions
- Class declarations
- Function expressions
- Method definitions
- TypeScript enum declarations
- TypeScript interface declarations
- TypeScript type alias declarations
- TypeScript property signatures
- Disable `@typescript-eslint/no-unnecessary-type-arguments` ([#426](https://github.com/MetaMask/eslint-config/pull/426))
- We decided that "unnecessary" type arguments make types easier to read sometimes, so we should allow them.
- Disable `promise/valid-params` because it's redundant in type-checked projects ([#425](https://github.com/MetaMask/eslint-config/pull/425))
Expand Down
18 changes: 17 additions & 1 deletion packages/typescript/rules-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,23 @@
"jsdoc/require-example": "off",
"jsdoc/require-file-overview": "off",
"jsdoc/require-hyphen-before-param-description": "off",
"jsdoc/require-jsdoc": "error",
"jsdoc/require-jsdoc": [
"error",
{
"require": {
"ClassDeclaration": true,
"FunctionDeclaration": true,
"MethodDefinition": true
},
"contexts": [
":not(Property, NewExpression, CallExpression) > ArrowFunctionExpression",
":not(Property, NewExpression, CallExpression) > FunctionExpression",
":not(TSModuleBlock) > TSInterfaceDeclaration",
":not(TSModuleBlock) > TSTypeAliasDeclaration",
"TSEnumDeclaration"
]
}
],
"jsdoc/require-param": "error",
"jsdoc/require-param-description": "error",
"jsdoc/require-param-name": "error",
Expand Down
51 changes: 50 additions & 1 deletion packages/typescript/src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
import { createConfig } from '@metamask/eslint-config';
import base, { createConfig } from '@metamask/eslint-config';
import * as resolver from 'eslint-import-resolver-typescript';
import importX from 'eslint-plugin-import-x';
import jsdoc from 'eslint-plugin-jsdoc';
// TODO: Look into why this doesn't resolve.
// eslint-disable-next-line import-x/no-unresolved
import typescript from 'typescript-eslint';

/**
* Collects all options for a given array-valued rule across one or more flat
* config arrays, excluding the leading severity element.
*
* ESLint flat config does not merge array-valued rules across config objects —
* a later config silently replaces earlier ones. This helper makes it possible
* to extend an upstream rule configuration rather than copy-pasting its options.
*
* @param {string} ruleName - The rule to collect options for.
* @param {import('eslint').Linter.Config[][]} configs - Flat config arrays to
* collect options from.
* @returns {unknown[]} The options from all matching rule entries, with the
* leading severity element omitted.
*/
function collectExistingRuleOptions(ruleName, configs) {
return configs.flat().flatMap((config) => {
const rule = config.rules?.[ruleName];
if (!Array.isArray(rule)) {
return [];
}
// Rule entries are ['error' | 'warn' | number, ...options].
// Skip the first element (severity) and collect the rest.
return rule.slice(1);
});
}

const baseJsdocRuleOptions = collectExistingRuleOptions(
'jsdoc/require-jsdoc',
base,
);

const config = createConfig({
name: '@metamask/eslint-config-typescript',

Expand Down Expand Up @@ -225,6 +256,24 @@ const config = createConfig({
// Use TypeScript types rather than JSDoc types.
'jsdoc/no-types': 'error',

// Extend rule defined in base config to require JSDoc for
// TypeScript-specific symbols.
'jsdoc/require-jsdoc': [
'error',
{
require: baseJsdocRuleOptions[0].require,
contexts: [
...baseJsdocRuleOptions[0].contexts,
// Type interfaces that are not defined within `declare` blocks
':not(TSModuleBlock) > TSInterfaceDeclaration',
// Type aliases that are not defined within `declare` blocks
':not(TSModuleBlock) > TSTypeAliasDeclaration',
// Enums
'TSEnumDeclaration',
],
},
],

// These all conflict with `jsdoc/no-types`.
'jsdoc/require-param-type': 'off',
'jsdoc/require-property-type': 'off',
Expand Down
Loading