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

Skip to content

Commit 8acf037

Browse files
committed
docs: add docs
1 parent f5c47db commit 8acf037

File tree

9 files changed

+218
-44
lines changed

9 files changed

+218
-44
lines changed

packages/eslint-plugin/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,13 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e
159159
| [`@typescript-eslint/member-delimiter-style`](./docs/rules/member-delimiter-style.md) | Require a specific member delimiter style for interfaces and type literals | :heavy_check_mark: | :wrench: | |
160160
| [`@typescript-eslint/member-naming`](./docs/rules/member-naming.md) | Enforces naming conventions for class members by visibility | | | |
161161
| [`@typescript-eslint/member-ordering`](./docs/rules/member-ordering.md) | Require a consistent member declaration order | | | |
162+
| [`@typescript-eslint/naming-convention`](./docs/rules/naming-convention.md) | Enforces naming conventions for everything across a codebase | | | :thought_balloon: |
162163
| [`@typescript-eslint/no-array-constructor`](./docs/rules/no-array-constructor.md) | Disallow generic `Array` constructors | :heavy_check_mark: | :wrench: | |
163164
| [`@typescript-eslint/no-dynamic-delete`](./docs/rules/no-dynamic-delete.md) | Bans usage of the delete operator with computed key expressions | | :wrench: | |
164165
| [`@typescript-eslint/no-empty-function`](./docs/rules/no-empty-function.md) | Disallow empty functions | :heavy_check_mark: | | |
165-
| [`@typescript-eslint/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces | :heavy_check_mark: | :wrench: |
166+
| [`@typescript-eslint/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces | :heavy_check_mark: | :wrench: | |
166167
| [`@typescript-eslint/no-explicit-any`](./docs/rules/no-explicit-any.md) | Disallow usage of the `any` type | :heavy_check_mark: | :wrench: | |
167-
| [`@typescript-eslint/no-extra-non-null-assertion`](./docs/rules/no-extra-non-null-assertion.md) | Disallow extra non-null assertion | | | |
168+
| [`@typescript-eslint/no-extra-non-null-assertion`](./docs/rules/no-extra-non-null-assertion.md) | Disallow extra non-null assertion | | | |
168169
| [`@typescript-eslint/no-extra-parens`](./docs/rules/no-extra-parens.md) | Disallow unnecessary parentheses | | :wrench: | |
169170
| [`@typescript-eslint/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces | | | |
170171
| [`@typescript-eslint/no-floating-promises`](./docs/rules/no-floating-promises.md) | Requires Promise-like values to be handled appropriately. | | | :thought_balloon: |
@@ -205,7 +206,7 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e
205206
| [`@typescript-eslint/require-await`](./docs/rules/require-await.md) | Disallow async functions which have no `await` expression | :heavy_check_mark: | | :thought_balloon: |
206207
| [`@typescript-eslint/restrict-plus-operands`](./docs/rules/restrict-plus-operands.md) | When adding two variables, operands must both be of type number or of type string | | | :thought_balloon: |
207208
| [`@typescript-eslint/restrict-template-expressions`](./docs/rules/restrict-template-expressions.md) | Enforce template literal expressions to be of string type | | | :thought_balloon: |
208-
| [`@typescript-eslint/return-await`](./docs/rules/return-await.md) | Rules for awaiting returned promises | | | :thought_balloon: |
209+
| [`@typescript-eslint/return-await`](./docs/rules/return-await.md) | Rules for awaiting returned promises | | | :thought_balloon: |
209210
| [`@typescript-eslint/semi`](./docs/rules/semi.md) | Require or disallow semicolons instead of ASI | | :wrench: | |
210211
| [`@typescript-eslint/space-before-function-paren`](./docs/rules/space-before-function-paren.md) | enforce consistent spacing before `function` definition opening parenthesis | | :wrench: | |
211212
| [`@typescript-eslint/strict-boolean-expressions`](./docs/rules/strict-boolean-expressions.md) | Restricts the types allowed in boolean expressions | | | :thought_balloon: |
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Enforces naming conventions for everything across a codebase (naming-convention)
2+
3+
Enforcing naming conventions helps keep the codebase consistent, and reduces overhead when thinking about how to name a variable.
4+
Additionally, a well designed style guide can help communicate intent, such as by enforcing all private properties begin with an `_`, and all global-level constants are written in `UPPER_CASE`.
5+
6+
There are many different rules that have existed over time, but they have had the problem of not having enough granularity, meaning it was hard to have a well defined style guide, and most of the time you needed 3 or more rules at once to enforce different conventions, hoping they didn't conflict.
7+
8+
## Rule Details
9+
10+
This rule allows you to enforce conventions for any identifier, using granular selectors to create a fine-grained style guide.
11+
By default, it enforces nothing.
12+
13+
### Note - this rule only needs type information in specfic cases, detailed below
14+
15+
## Options
16+
17+
This rule accepts an array of objects, with each object describing a different naming convention.
18+
Each property will be described in detail below. Also see the examples section below for illustrated examples.
19+
20+
```ts
21+
type Options = {
22+
// format options
23+
format: (
24+
| 'camelCase'
25+
| 'strictCamelCase'
26+
| 'PascalCase'
27+
| 'StrictPascalCase'
28+
| 'snake_case'
29+
| 'UPPER_CASE'
30+
)[];
31+
leadingUnderscore?: 'forbid' | 'allow' | 'require';
32+
trailingUnderscore?: 'forbid' | 'allow' | 'require';
33+
prefix?: string[];
34+
suffix?: string[];
35+
36+
// selector options
37+
selector: Selector;
38+
modifiers?: Modifiers<Selector>[];
39+
types?: Types<Selector>[];
40+
filter?: string;
41+
}[];
42+
43+
const defaultOptions: Options = [];
44+
```
45+
46+
### Format Options
47+
48+
Every single selector can have the same set of format options.
49+
When the format of an identifier is checked, it is checked in the following order:
50+
51+
1. validate leading underscore
52+
1. validate trailing underscore
53+
1. validate prefix
54+
1. validate suffix
55+
1. validate format
56+
57+
At each step, if the identifier matches the options, it the matching part will be removed.
58+
For example, if you provide the following formating option: `{ leadingUnderscore: 'allow', prefix: ['I'], format: ['StrictPascalCase'] }`, for the identifier `_IMyInterface`, then the following checks will occur:
59+
60+
1. `name = _IMyInterface`
61+
1. validate leading underscore - pass
62+
- Trim leading underscore - `name = IMyInterface`
63+
1. validate trailing underscore - no check
64+
1. validate prefix - pass
65+
- Trim prefix - `name = MyInterface`
66+
1. validate suffix - no check
67+
1. validate format - pass
68+
69+
#### `format`
70+
71+
The `format` option defines the allowed formats for the identifier. This option accepts an array of the following values, and the identifier can match any of them:
72+
73+
- `camelCase` - standard camelCase format - no underscores are allowed between characters, and consecutive capitals are allowed (i.e. both `myID` and `myId` are valid).
74+
- `strictCamelCase` - same as `camelCase`, but consecutive capitals are not allowed (i.e. `myId` is valid, but `myID` is not).
75+
- `PascalCase` - same as `camelCase`, except the first character must be upper-case.
76+
- `StrictPascalCase` - same as `strictCamelCase`, except the first character must be upper-case.
77+
- `snake_case` - standard snake_case format - all characters must be lower-case, and underscores are allowed.
78+
- `UPPER_CASE` - same as `snake_case`, except all characters must be upper-case.
79+
80+
#### `leadingUnderscore` / `trailingUnderscore`
81+
82+
The `leadingUnderscore` / `trailingUnderscore` options control whether leading/trailing underscores are considered valid. Accepts one of the following values:
83+
84+
- `forbid` - a leading/trailing underscore is not allowed at all.
85+
- `allow` - existence of a leading/trailing underscore is not explicitly enforced.
86+
- `require` - a leading/trailing underscores must be included.
87+
88+
#### `prefix` / `suffix`
89+
90+
The `prefix` / `suffix` options control which prefix/suffix strings must exist for the identifier. Accepts an array of strings.
91+
92+
If these are provided, the identifier must start with one of the provided values. For example, if you provide `{ prefix: ['IFace', 'Class', 'Type'] }`, then the following names are valid: `IFaceFoo`, `ClassBar`, `TypeBaz`, but the name `Bang` is not valid, as it contains none of the prefixes.
93+
94+
### Selector Options
95+
96+
The selector options determine which names that the formatting options will apply to.
97+
Each value for `selector` has a set of `types` and `modifiers` that are allowed to be used with it, which are explained below.
98+
99+
`modifiers` allows you to specify which modifiers to granularly apply to, such as the accessibility (`private`/`public`/`protected`), or if the thing is `static`, etc. The name must match _all_ of the modifiers. For example, if you provide `{ modifiers: ['private', 'static', 'readonly'] }`, then it will only match something that is `private static readonly`, and something that is just `private` will not match.
100+
101+
`types` allows you to specify which types to match. This option supports simple, primitive types only (`boolean`, `string`, `number`, `function`, `array`). This lets you do things like enforce that `boolean` variables are prefixed with a verb.
102+
**_NOTE - Using this option will require that you lint with type information._**
103+
104+
`filter` accepts a regular expression (anything accepted into `new RegExp(filter)`). It allows you to limit the scope of this configuration to names that match this regex.
105+
106+
#### Allowed Selectors
107+
108+
There are two types of selectors, individual selectors, and grouped selectors.
109+
110+
Individual Selectors match specific, well-defined sets. There is no overlap between each of the individual selectors.
111+
112+
- `variable` - matches any `var` / `let` / `const` variable name.
113+
- Allowed `modifiers`: none.
114+
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
115+
- `function` - matches any named function declaration or named function expression.
116+
- Allowed `modifiers`: none.
117+
- Allowed `types`: none.
118+
- `parameter` - matches any function parameter. Does not match parameter properties.
119+
- Allowed `modifiers`: none.
120+
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
121+
- `property` - matches any object, class, or object type property. Does not match properties that have direct function expression or arrow function expression values.
122+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`.
123+
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
124+
- `parameterProperty` - matches any parameter property.
125+
- Allowed `modifiers`: `private`, `protected`, `public`, `readonly`.
126+
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
127+
- `method` - matches any object, class, or object type method. Also matches properties that have direct function expression or arrow function expression values. Does not match accessors.
128+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`.
129+
- Allowed `types`: none.
130+
- `accessor` - matches any accessor.
131+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`.
132+
- Allowed `types`: `boolean`, `string`, `number`, `function`, `array`.
133+
- `enumMember` - matches any enum member.
134+
- Allowed `modifiers`: none.
135+
- Allowed `types`: none.
136+
- `class` - matches any class declaration.
137+
- Allowed `modifiers`: `abstract`.
138+
- Allowed `types`: none.
139+
- `interface` - matches any interface declaration.
140+
- Allowed `modifiers`: none.
141+
- Allowed `types`: none.
142+
- `typeAlias` - matches any type alias declaration.
143+
- Allowed `modifiers`: none.
144+
- Allowed `types`: none.
145+
- `enum` - matches any enum declaration.
146+
- Allowed `modifiers`: none.
147+
- Allowed `types`: none.
148+
- `typeParameter` - matches any generic type parameter declaration.
149+
- Allowed `modifiers`: none.
150+
- Allowed `types`: none.
151+
152+
Group Selectors are provided for convenience, and essentially bundle up sets of individual selectors.
153+
154+
- `default` - matches everything.
155+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`.
156+
- Allowed `types`: none.
157+
- `variableLike` - matches the same as `variable`, `function` and `parameter`.
158+
- Allowed `modifiers`: none.
159+
- Allowed `types`: none.
160+
- `memberLike` - matches the same as `property`, `parameterProperty`, `method`, `accessor`, `enumMember`.
161+
- Allowed `modifiers`: `private`, `protected`, `public`, `static`, `readonly`, `abstract`.
162+
- Allowed `types`: none.
163+
- `typeLike` - matches the same as `class`, `interface`, `typeAlias`, `enum`, `typeParameter`.
164+
- Allowed `modifiers`: `abstract`.
165+
- Allowed `types`: none.
166+
167+
The ordering of selectors does not matter. The implementation will automatically sort the selectors to ensure they match from most-specific to least specific. It will keep checking selectors in that order until it finds one that matches the name.
168+
169+
For example, if you provide the following config:
170+
171+
```ts
172+
[
173+
/* 1 */ { selector: 'default', format: ['camelCase'] },
174+
/* 2 */ { selector: 'variable', format: ['snake_case'] },
175+
/* 3 */ { selector: 'variable', type: ['boolean'], format: ['UPPER_CASE'] },
176+
/* 4 */ { selector: 'variableLike', format: ['PascalCase'] },
177+
];
178+
```
179+
180+
Then the rule will validate the selectors in the following order: `3`, `2`, `4`, `1`.
181+
182+
## When Not To Use It
183+
184+
If you do not want to enforce naming conventions for anything.

packages/eslint-plugin/src/configs/all.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,18 @@
88
"@typescript-eslint/ban-types": "error",
99
"brace-style": "off",
1010
"@typescript-eslint/brace-style": "error",
11-
"camelcase": "off",
12-
"@typescript-eslint/camelcase": "error",
13-
"@typescript-eslint/class-name-casing": "error",
1411
"@typescript-eslint/consistent-type-assertions": "error",
1512
"@typescript-eslint/consistent-type-definitions": "error",
1613
"@typescript-eslint/explicit-function-return-type": "error",
1714
"@typescript-eslint/explicit-member-accessibility": "error",
1815
"func-call-spacing": "off",
1916
"@typescript-eslint/func-call-spacing": "error",
20-
"@typescript-eslint/generic-type-naming": "error",
2117
"indent": "off",
2218
"@typescript-eslint/indent": "error",
2319
"@typescript-eslint/interface-name-prefix": "error",
2420
"@typescript-eslint/member-delimiter-style": "error",
25-
"@typescript-eslint/member-naming": "error",
2621
"@typescript-eslint/member-ordering": "error",
22+
"@typescript-eslint/naming-convention": "error",
2723
"no-array-constructor": "off",
2824
"@typescript-eslint/no-array-constructor": "error",
2925
"@typescript-eslint/no-dynamic-delete": "error",

packages/eslint-plugin/src/rules/camelcase.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export default util.createRule<Options, MessageIds>({
3030
category: 'Stylistic Issues',
3131
recommended: 'error',
3232
},
33+
deprecated: true,
34+
replacedBy: ['naming-convention'],
3335
schema: [schema],
3436
messages: baseRule.meta.messages,
3537
},

packages/eslint-plugin/src/rules/class-name-casing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export default util.createRule<Options, MessageIds>({
2020
category: 'Best Practices',
2121
recommended: 'error',
2222
},
23+
deprecated: true,
24+
replacedBy: ['naming-convention'],
2325
messages: {
2426
notPascalCased: "{{friendlyName}} '{{name}}' must be PascalCased.",
2527
},

packages/eslint-plugin/src/rules/generic-type-naming.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export default util.createRule<Options, MessageIds>({
1313
// too opinionated to be recommended
1414
recommended: false,
1515
},
16+
deprecated: true,
17+
replacedBy: ['naming-convention'],
1618
messages: {
1719
paramNotMatchRule:
1820
'Type parameter {{name}} does not match rule {{rule}}.',

packages/eslint-plugin/src/rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import interfaceNamePrefix from './interface-name-prefix';
1717
import memberDelimiterStyle from './member-delimiter-style';
1818
import memberNaming from './member-naming';
1919
import memberOrdering from './member-ordering';
20+
import namingConvention from './naming-convention';
2021
import noArrayConstructor from './no-array-constructor';
2122
import noDynamicDelete from './no-dynamic-delete';
2223
import noEmptyFunction from './no-empty-function';
@@ -93,6 +94,7 @@ export default {
9394
'member-delimiter-style': memberDelimiterStyle,
9495
'member-naming': memberNaming,
9596
'member-ordering': memberOrdering,
97+
'naming-convention': namingConvention,
9698
'no-array-constructor': noArrayConstructor,
9799
'no-dynamic-delete': noDynamicDelete,
98100
'no-empty-function': noEmptyFunction,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export default util.createRule<Options, MessageIds>({
2323
category: 'Stylistic Issues',
2424
recommended: false,
2525
},
26+
deprecated: true,
27+
replacedBy: ['naming-convention'],
2628
messages: {
2729
incorrectName:
2830
'{{accessibility}} property {{name}} should match {{convention}}.',

0 commit comments

Comments
 (0)