Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 156d058

Browse files
authored
feat(eslint-plugin): [naming-convention] allow selecting only const variables (typescript-eslint#2291)
1 parent 2c90d9f commit 156d058

File tree

3 files changed

+56
-10
lines changed

3 files changed

+56
-10
lines changed

packages/eslint-plugin/docs/rules/naming-convention.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ There are two types of selectors, individual selectors, and grouped selectors.
192192
Individual Selectors match specific, well-defined sets. There is no overlap between each of the individual selectors.
193193

194194
- `variable` - matches any `var` / `let` / `const` variable name.
195-
- Allowed `modifiers`: none.
195+
- Allowed `modifiers`: `const`.
196196
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
197197
- `function` - matches any named function declaration or named function expression.
198198
- Allowed `modifiers`: none.
@@ -309,6 +309,21 @@ Group Selectors are provided for convenience, and essentially bundle up sets of
309309
}
310310
```
311311

312+
### Enforce that all const variables are in UPPER_CASE
313+
314+
```json
315+
{
316+
"@typescript-eslint/naming-convention": [
317+
"error",
318+
{
319+
"selector": "variable",
320+
"modifiers": ["const"],
321+
"format": ["UPPER_CASE"]
322+
}
323+
]
324+
}
325+
```
326+
312327
### Enforce that type parameters (generics) are prefixed with `T`
313328

314329
This allows you to emulate the old `generic-type-naming` rule.

packages/eslint-plugin/src/rules/naming-convention.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,13 @@ type MetaSelectorsString = keyof typeof MetaSelectors;
8080
type IndividualAndMetaSelectorsString = SelectorsString | MetaSelectorsString;
8181

8282
enum Modifiers {
83-
readonly = 1 << 0,
84-
static = 1 << 1,
85-
public = 1 << 2,
86-
protected = 1 << 3,
87-
private = 1 << 4,
88-
abstract = 1 << 5,
83+
const = 1 << 0,
84+
readonly = 1 << 1,
85+
static = 1 << 2,
86+
public = 1 << 3,
87+
protected = 1 << 4,
88+
private = 1 << 5,
89+
abstract = 1 << 6,
8990
}
9091
type ModifiersString = keyof typeof Modifiers;
9192

@@ -255,7 +256,7 @@ const SCHEMA: JSONSchema.JSONSchema4 = {
255256
...selectorSchema('default', false, util.getEnumNames(Modifiers)),
256257

257258
...selectorSchema('variableLike', false),
258-
...selectorSchema('variable', true),
259+
...selectorSchema('variable', true, ['const']),
259260
...selectorSchema('function', false),
260261
...selectorSchema('parameter', true),
261262

@@ -439,8 +440,18 @@ export default util.createRule<Options, MessageIds>({
439440
const identifiers: TSESTree.Identifier[] = [];
440441
getIdentifiersFromPattern(node.id, identifiers);
441442

443+
const modifiers = new Set<Modifiers>();
444+
const parent = node.parent;
445+
if (
446+
parent &&
447+
parent.type === AST_NODE_TYPES.VariableDeclaration &&
448+
parent.kind === 'const'
449+
) {
450+
modifiers.add(Modifiers.const);
451+
}
452+
442453
identifiers.forEach(i => {
443-
validator(i);
454+
validator(i, modifiers);
444455
});
445456
},
446457

packages/eslint-plugin/tests/rules/naming-convention.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,10 @@ ruleTester.run('naming-convention', rule, {
626626
},
627627
{
628628
code: `
629+
declare const ANY_UPPER_CASE: any;
630+
declare const ANY_UPPER_CASE: any | null;
631+
declare const ANY_UPPER_CASE: any | null | undefined;
632+
629633
declare const string_camelCase: string;
630634
declare const string_camelCase: string | null;
631635
declare const string_camelCase: string | null | undefined;
@@ -647,6 +651,12 @@ ruleTester.run('naming-convention', rule, {
647651
`,
648652
parserOptions,
649653
options: [
654+
{
655+
selector: 'variable',
656+
modifiers: ['const'],
657+
format: ['UPPER_CASE'],
658+
prefix: ['ANY_'],
659+
},
650660
{
651661
selector: 'variable',
652662
types: ['string'],
@@ -824,6 +834,10 @@ ruleTester.run('naming-convention', rule, {
824834
},
825835
{
826836
code: `
837+
declare const any_camelCase01: any;
838+
declare const any_camelCase02: any | null;
839+
declare const any_camelCase03: any | null | undefined;
840+
827841
declare const string_camelCase01: string;
828842
declare const string_camelCase02: string | null;
829843
declare const string_camelCase03: string | null | undefined;
@@ -844,6 +858,12 @@ ruleTester.run('naming-convention', rule, {
844858
declare const boolean_camelCase16: true | false | null | undefined;
845859
`,
846860
options: [
861+
{
862+
selector: 'variable',
863+
modifiers: ['const'],
864+
format: ['UPPER_CASE'],
865+
prefix: ['any_'],
866+
},
847867
{
848868
selector: 'variable',
849869
types: ['string'],
@@ -864,7 +884,7 @@ ruleTester.run('naming-convention', rule, {
864884
},
865885
],
866886
parserOptions,
867-
errors: Array(16).fill({ messageId: 'doesNotMatchFormatTrimmed' }),
887+
errors: Array(19).fill({ messageId: 'doesNotMatchFormatTrimmed' }),
868888
},
869889
{
870890
code: `

0 commit comments

Comments
 (0)