@aneuhold/eslint-config 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/rules/no-private-modifier/classReports.ts +0 -2
- package/src/rules/no-private-modifier/no-private-modifier.md +6 -3
- package/src/rules/no-private-modifier/no-private-modifier.test.ts +2 -6
- package/src/rules/no-private-modifier/no-private-modifier.ts +3 -5
- package/src/rules/no-private-modifier/types.ts +1 -1
package/package.json
CHANGED
|
@@ -30,9 +30,7 @@ export const collectClassReports = (frame: ClassFrame): ClassReports => {
|
|
|
30
30
|
if (member.accessibility !== 'private') {
|
|
31
31
|
continue;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
33
|
if (member.type === AST_NODE_TYPES.MethodDefinition && member.kind === 'constructor') {
|
|
35
|
-
reports.push({ member, messageId: 'privateConstructor' });
|
|
36
34
|
continue;
|
|
37
35
|
}
|
|
38
36
|
|
|
@@ -14,11 +14,14 @@ Every form of the `private` modifier on a class member is reported:
|
|
|
14
14
|
|
|
15
15
|
- Instance and `static` fields, including `accessor` properties.
|
|
16
16
|
- Instance and `static` methods, getters, and setters.
|
|
17
|
-
- Constructors (`private constructor() {}`).
|
|
18
17
|
|
|
19
18
|
`public` and `protected` members, and members with no modifier, are left alone —
|
|
20
19
|
this rule is only concerned with replacing `private`.
|
|
21
20
|
|
|
21
|
+
**Private constructors are allowed.** `private constructor() {}` has no `#`
|
|
22
|
+
equivalent — a constructor cannot be a `#private` member — and restricting
|
|
23
|
+
construction this way (e.g. to force a static factory) is a valid pattern.
|
|
24
|
+
|
|
22
25
|
**Constructor parameter properties are allowed.** `constructor(private foo: T)`
|
|
23
26
|
is a concise, readable shorthand that declares and assigns the field in one
|
|
24
27
|
place, and `#private` has no equivalent. Flagging it would force the verbose
|
|
@@ -42,8 +45,6 @@ class Counter {
|
|
|
42
45
|
private accessor label = '';
|
|
43
46
|
|
|
44
47
|
private increment(): void {}
|
|
45
|
-
|
|
46
|
-
private constructor() {}
|
|
47
48
|
}
|
|
48
49
|
```
|
|
49
50
|
|
|
@@ -56,6 +57,8 @@ class Counter {
|
|
|
56
57
|
accessor #label = '';
|
|
57
58
|
|
|
58
59
|
#increment(): void {}
|
|
60
|
+
|
|
61
|
+
private constructor() {}
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
class Service {
|
|
@@ -22,6 +22,8 @@ ruleTester.run('no-private-modifier', noPrivateModifier, {
|
|
|
22
22
|
{ code: `class Foo { accessor #x = 1; }` },
|
|
23
23
|
{ code: `class Foo { get #x(): number { return 1; } }` },
|
|
24
24
|
{ code: `class Foo { constructor(foo: string) {} }` },
|
|
25
|
+
// Private constructors are allowed (no `#` constructor exists).
|
|
26
|
+
{ code: `class Foo { private constructor() {} }` },
|
|
25
27
|
// Constructor parameter properties are allowed (no `#` shorthand exists).
|
|
26
28
|
{ code: `class Foo { constructor(private foo: string) {} }` },
|
|
27
29
|
{ code: `class Foo { constructor(private readonly foo: string) {} }` },
|
|
@@ -75,12 +77,6 @@ ruleTester.run('no-private-modifier', noPrivateModifier, {
|
|
|
75
77
|
errors: [{ messageId: 'privateField' }, { messageId: 'privateMethod' }],
|
|
76
78
|
output: `class Foo { #count = 0; #helper() { return this.#count; } }`,
|
|
77
79
|
},
|
|
78
|
-
// Private constructor: reported, never fixed.
|
|
79
|
-
{
|
|
80
|
-
code: `class Foo { private constructor() {} }`,
|
|
81
|
-
errors: [{ messageId: 'privateConstructor' }],
|
|
82
|
-
output: null,
|
|
83
|
-
},
|
|
84
80
|
// Possible cross-instance access (`other.id`) is ambiguous, so no fix.
|
|
85
81
|
{
|
|
86
82
|
code: `class Foo { private id = 1; eq(other: Foo): boolean { return this.id === other.id; } }`,
|
|
@@ -10,9 +10,9 @@ import { type ClassFrame, type ClassNode } from './types';
|
|
|
10
10
|
* syntax rather than the TypeScript `private` accessibility modifier, and
|
|
11
11
|
* autofixes the conversion — declaration plus `this.x` / `ClassName.x`
|
|
12
12
|
* references — whenever it can do so safely. Covers instance and static fields,
|
|
13
|
-
* methods (including accessors and getters/setters)
|
|
14
|
-
*
|
|
15
|
-
* intentionally allowed, since the `#` form has no equivalent
|
|
13
|
+
* and methods (including accessors and getters/setters). Private constructors
|
|
14
|
+
* and constructor parameter properties (`constructor(private foo)`) are
|
|
15
|
+
* intentionally allowed, since the `#` form has no equivalent.
|
|
16
16
|
*
|
|
17
17
|
* References are gathered as ESLint makes its single pass over the file: a stack
|
|
18
18
|
* tracks the class currently being traversed, and a per-class counter tracks how
|
|
@@ -33,8 +33,6 @@ export const noPrivateModifier = createRule({
|
|
|
33
33
|
'Use a `#private` field instead of the TypeScript `private` modifier (e.g. `#count` rather than `private count`).',
|
|
34
34
|
privateMethod:
|
|
35
35
|
'Use a `#private` method instead of the TypeScript `private` modifier (e.g. `#helper()` rather than `private helper()`).',
|
|
36
|
-
privateConstructor:
|
|
37
|
-
'A constructor cannot become a `#private` member; drop the `private` modifier (consider a static factory if construction must be restricted).',
|
|
38
36
|
},
|
|
39
37
|
schema: [],
|
|
40
38
|
},
|
|
@@ -10,7 +10,7 @@ export type FixableMember =
|
|
|
10
10
|
| TSESTree.MethodDefinition;
|
|
11
11
|
|
|
12
12
|
/** A message this rule can report. */
|
|
13
|
-
export type MessageId = 'privateField' | 'privateMethod'
|
|
13
|
+
export type MessageId = 'privateField' | 'privateMethod';
|
|
14
14
|
|
|
15
15
|
/** A member to convert, paired with the references that convert alongside it. */
|
|
16
16
|
export type FixTarget = { member: FixableMember; refs: TSESTree.MemberExpression[] };
|