Skip to content

Commit

Permalink
feat(eslint-plugin): add extension rule init-declarations (#1814)
Browse files Browse the repository at this point in the history
Co-authored-by: Brad Zacher <brad.zacher@gmail.com>
  • Loading branch information
anikethsaha and bradzacher committed Apr 20, 2020
1 parent cea51bf commit b01f5e7
Show file tree
Hide file tree
Showing 7 changed files with 826 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/eslint-plugin/README.md
Expand Up @@ -183,6 +183,7 @@ In these cases, we create what we call an extension rule; a rule within our plug
| [`@typescript-eslint/default-param-last`](./docs/rules/default-param-last.md) | Enforce default parameters to be last | | | |
| [`@typescript-eslint/func-call-spacing`](./docs/rules/func-call-spacing.md) | Require or disallow spacing between function identifiers and their invocations | | :wrench: | |
| [`@typescript-eslint/indent`](./docs/rules/indent.md) | Enforce consistent indentation | | :wrench: | |
| [`@typescript-eslint/init-declarations`](./docs/rules/init-declarations.md) | require or disallow initialization in variable declarations | | | |
| [`@typescript-eslint/keyword-spacing`](./docs/rules/keyword-spacing.md) | Enforce consistent spacing before and after keywords | | :wrench: | |
| [`@typescript-eslint/no-array-constructor`](./docs/rules/no-array-constructor.md) | Disallow generic `Array` constructors | :heavy_check_mark: | :wrench: | |
| [`@typescript-eslint/no-dupe-class-members`](./docs/rules/no-dupe-class-members.md) | Disallow duplicate class members | | | |
Expand Down
22 changes: 22 additions & 0 deletions packages/eslint-plugin/docs/rules/init-declarations.md
@@ -0,0 +1,22 @@
# require or disallow initialization in variable declarations (`init-declarations`)

## Rule Details

This rule extends the base [`eslint/init-declarations`](https://eslint.org/docs/rules/init-declarations) rule.
It adds support for TypeScript's `declare` variables.

## How to use

```cjson
{
// note you must disable the base rule as it can report incorrect errors
"init-declarations": "off",
"@typescript-eslint/init-declarations": ["error"]
}
```

## Options

See [`eslint/init-declarations` options](https://eslint.org/docs/rules/init-declarations#options).

<sup>Taken with ❤️ [from ESLint core](https://github.com/eslint/eslint/blob/master/docs/rules/init-declarations.md)</sup>
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/configs/all.json
Expand Up @@ -22,6 +22,8 @@
"@typescript-eslint/func-call-spacing": "error",
"indent": "off",
"@typescript-eslint/indent": "error",
"init-declarations": "off",
"@typescript-eslint/init-declarations": "error",
"keyword-spacing": "off",
"@typescript-eslint/keyword-spacing": "error",
"@typescript-eslint/member-delimiter-style": "error",
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Expand Up @@ -87,6 +87,7 @@ import requireAwait from './require-await';
import restrictPlusOperands from './restrict-plus-operands';
import restrictTemplateExpressions from './restrict-template-expressions';
import returnAwait from './return-await';
import initDeclarations from './init-declarations';
import semi from './semi';
import spaceBeforeFunctionParen from './space-before-function-paren';
import strictBooleanExpressions from './strict-boolean-expressions';
Expand Down Expand Up @@ -118,6 +119,7 @@ export default {
'func-call-spacing': funcCallSpacing,
'generic-type-naming': genericTypeNaming,
indent: indent,
'init-declarations': initDeclarations,
'interface-name-prefix': interfaceNamePrefix,
'keyword-spacing': keywordSpacing,
'member-delimiter-style': memberDelimiterStyle,
Expand Down
53 changes: 53 additions & 0 deletions packages/eslint-plugin/src/rules/init-declarations.ts
@@ -0,0 +1,53 @@
import {
TSESTree,
AST_NODE_TYPES,
} from '@typescript-eslint/experimental-utils';
import baseRule from 'eslint/lib/rules/init-declarations';
import {
InferOptionsTypeFromRule,
InferMessageIdsTypeFromRule,
createRule,
} from '../util';

export type Options = InferOptionsTypeFromRule<typeof baseRule>;
export type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;

export default createRule<Options, MessageIds>({
name: 'init-declarations',
meta: {
type: 'suggestion',
docs: {
description:
'require or disallow initialization in variable declarations',
category: 'Variables',
recommended: false,
extendsBaseRule: true,
},
schema: baseRule.meta.schema,
messages: baseRule.meta.messages,
},
defaultOptions: ['always'],
create(context) {
const rules = baseRule.create(context);
const mode = context.options[0] || 'always';

return {
'VariableDeclaration:exit'(node: TSESTree.VariableDeclaration): void {
if (mode === 'always') {
if (node.declare) {
return;
}
if (
node.parent?.type === AST_NODE_TYPES.TSModuleBlock &&
node.parent.parent?.type === AST_NODE_TYPES.TSModuleDeclaration &&
node.parent.parent?.declare
) {
return;
}
}

rules['VariableDeclaration:exit'](node);
},
};
},
});

0 comments on commit b01f5e7

Please sign in to comment.