eslint-config-typed 4.0.6 → 4.0.8

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.
Files changed (31) hide show
  1. package/dist/configs/typescript.d.mts.map +1 -1
  2. package/dist/configs/typescript.mjs +2 -0
  3. package/dist/configs/typescript.mjs.map +1 -1
  4. package/dist/plugins/react-coding-style/rules/display-name.d.mts +2 -2
  5. package/dist/plugins/react-coding-style/rules/display-name.d.mts.map +1 -1
  6. package/dist/plugins/react-coding-style/rules/display-name.mjs +110 -30
  7. package/dist/plugins/react-coding-style/rules/display-name.mjs.map +1 -1
  8. package/dist/plugins/react-coding-style/rules/rules.d.mts +2 -2
  9. package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.mjs +18 -9
  10. package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.mjs.map +1 -1
  11. package/dist/rules/eslint-react-coding-style-rules.d.mts +1 -3
  12. package/dist/rules/eslint-react-coding-style-rules.d.mts.map +1 -1
  13. package/dist/rules/eslint-react-coding-style-rules.mjs +1 -1
  14. package/dist/rules/eslint-react-coding-style-rules.mjs.map +1 -1
  15. package/dist/rules/eslint-react-rules.d.mts +1 -1
  16. package/dist/rules/eslint-react-rules.mjs +1 -1
  17. package/dist/rules/eslint-react-rules.mjs.map +1 -1
  18. package/dist/types/rules/eslint-react-coding-style-rules.d.mts +21 -6
  19. package/dist/types/rules/eslint-react-coding-style-rules.d.mts.map +1 -1
  20. package/package.json +11 -9
  21. package/src/configs/typescript.mts +4 -0
  22. package/src/plugins/react-coding-style/README.md +4 -3
  23. package/src/plugins/react-coding-style/rules/display-name.mts +160 -38
  24. package/src/plugins/react-coding-style/rules/display-name.test.mts +70 -6
  25. package/src/plugins/react-coding-style/rules/shared.test.mts +148 -0
  26. package/src/plugins/react-coding-style/rules/use-memo-hooks-style-named.test.mts +47 -11
  27. package/src/plugins/react-coding-style/rules/use-memo-hooks-style-namespace.test.mts +47 -11
  28. package/src/plugins/react-coding-style/rules/use-memo-hooks-style.mts +24 -9
  29. package/src/rules/eslint-react-coding-style-rules.mts +1 -1
  30. package/src/rules/eslint-react-rules.mts +1 -1
  31. package/src/types/rules/eslint-react-coding-style-rules.mts +21 -6
@@ -28,12 +28,14 @@ describe('use-memo-hooks-style', () => {
28
28
  import * as React from 'react';
29
29
 
30
30
  type Props = Readonly<{
31
- readonly value: number;
31
+ value: number;
32
32
  }>;
33
33
 
34
34
  const Component = React.memo<Props>((props) => {
35
35
  const memoized = React.useMemo<number>(() => props.value, [props.value]);
36
+
36
37
  const typed: number = React.useMemo(() => props.value, [props.value]);
38
+
37
39
  return <div />;
38
40
  });
39
41
  `,
@@ -54,6 +56,40 @@ describe('use-memo-hooks-style', () => {
54
56
  const value = useMemo(() => 42) as number;
55
57
  `,
56
58
  },
59
+ {
60
+ name: 'Allow satisfies expression',
61
+ code: dedent`
62
+ import * as React from 'react';
63
+
64
+ type Props = Readonly<{
65
+ value: number;
66
+ }>;
67
+
68
+ const Component = React.memo<Props>((props) => {
69
+ const value = React.useMemo(() => props.value, [props.value]) satisfies number;
70
+
71
+ const inner = React.useMemo(() => props.value satisfies number, [props.value]);
72
+
73
+ return inner + value;
74
+ });
75
+ `,
76
+ },
77
+ {
78
+ name: 'Allow const assertion',
79
+ code: dedent`
80
+ import * as React from 'react';
81
+
82
+ type Props = Readonly<{
83
+ value: number;
84
+ }>;
85
+
86
+ const Component = React.memo<Props>((props) => {
87
+ const value = React.useMemo(() => ({ v: props.value }) as const, [props.value]);
88
+
89
+ return value;
90
+ });
91
+ `,
92
+ },
57
93
  ],
58
94
  invalid: [
59
95
  {
@@ -62,7 +98,7 @@ describe('use-memo-hooks-style', () => {
62
98
  import * as React from 'react';
63
99
 
64
100
  type Props = Readonly<{
65
- readonly value: number;
101
+ value: number;
66
102
  }>;
67
103
 
68
104
  const Component = React.memo<Props>((props) => {
@@ -82,7 +118,7 @@ describe('use-memo-hooks-style', () => {
82
118
  import * as React from 'react';
83
119
 
84
120
  type Props = Readonly<{
85
- readonly value: number;
121
+ value: number;
86
122
  }>;
87
123
 
88
124
  const Component = React.memo<Props>((props) => {
@@ -102,11 +138,11 @@ describe('use-memo-hooks-style', () => {
102
138
  import * as React from 'react';
103
139
 
104
140
  type Props = Readonly<{
105
- readonly value: number;
141
+ value: number;
106
142
  }>;
107
143
 
108
144
  const Component = React.memo<Props>((props) => {
109
- const value = React.useMemo(() => props.value as number, [props.value]) ;
145
+ const value = React.useMemo(() => props.value as number, [props.value]);
110
146
  return value;
111
147
  });
112
148
  `,
@@ -117,16 +153,16 @@ describe('use-memo-hooks-style', () => {
117
153
  ],
118
154
  },
119
155
  {
120
- name: 'Disallow satisfies expression',
156
+ name: 'Disallow return type annotation even with satisfies',
121
157
  code: dedent`
122
158
  import * as React from 'react';
123
159
 
124
160
  type Props = Readonly<{
125
- readonly value: number;
161
+ value: number;
126
162
  }>;
127
163
 
128
164
  const Component = React.memo<Props>((props) => {
129
- const value = React.useMemo(() => props.value, [props.value]) satisfies number;
165
+ const value = React.useMemo((): number => props.value, [props.value]) satisfies number;
130
166
  return value;
131
167
  });
132
168
  `,
@@ -137,16 +173,16 @@ describe('use-memo-hooks-style', () => {
137
173
  ],
138
174
  },
139
175
  {
140
- name: 'Disallow satisfies expression (inner)',
176
+ name: 'Disallow return type annotation even with const assertion',
141
177
  code: dedent`
142
178
  import * as React from 'react';
143
179
 
144
180
  type Props = Readonly<{
145
- readonly value: number;
181
+ value: number;
146
182
  }>;
147
183
 
148
184
  const Component = React.memo<Props>((props) => {
149
- const value = React.useMemo(() => props.value satisfies number, [props.value]);
185
+ const value = React.useMemo((): number => props.value, [props.value]) as const;
150
186
  return value;
151
187
  });
152
188
  `,
@@ -30,9 +30,9 @@ export const useMemoHooksStyleRule: TSESLint.RuleModule<MessageIds> = {
30
30
  const parent = node.parent;
31
31
 
32
32
  if (
33
- parent.type === AST_NODE_TYPES.TSAsExpression ||
34
- parent.type === AST_NODE_TYPES.TSTypeAssertion ||
35
- parent.type === AST_NODE_TYPES.TSSatisfiesExpression
33
+ (parent.type === AST_NODE_TYPES.TSAsExpression ||
34
+ parent.type === AST_NODE_TYPES.TSTypeAssertion) &&
35
+ !isConstAssertion(parent.typeAnnotation)
36
36
  ) {
37
37
  context.report({
38
38
  node: castDeepMutable(parent),
@@ -72,13 +72,14 @@ const checkNodeForTypeAnnotations = (
72
72
  ): void => {
73
73
  if (
74
74
  node.type === AST_NODE_TYPES.TSAsExpression ||
75
- node.type === AST_NODE_TYPES.TSTypeAssertion ||
76
- node.type === AST_NODE_TYPES.TSSatisfiesExpression
75
+ node.type === AST_NODE_TYPES.TSTypeAssertion
77
76
  ) {
78
- context.report({
79
- node: castDeepMutable(node),
80
- messageId: 'disallowUseMemoTypeAnnotation',
81
- });
77
+ if (!isConstAssertion(node.typeAnnotation)) {
78
+ context.report({
79
+ node: castDeepMutable(node),
80
+ messageId: 'disallowUseMemoTypeAnnotation',
81
+ });
82
+ }
82
83
 
83
84
  return;
84
85
  }
@@ -116,3 +117,17 @@ const checkNodeForTypeAnnotations = (
116
117
  );
117
118
  }
118
119
  };
120
+
121
+ const isConstAssertion = (
122
+ node: DeepReadonly<TSESTree.Node> | undefined,
123
+ ): node is TSESTree.TSTypeReference => {
124
+ if (node === undefined) {
125
+ return false;
126
+ }
127
+
128
+ return (
129
+ node.type === AST_NODE_TYPES.TSTypeReference &&
130
+ node.typeName.type === AST_NODE_TYPES.Identifier &&
131
+ node.typeName.name === 'const'
132
+ );
133
+ };
@@ -11,5 +11,5 @@ export const eslintReactCodingStyleRules = {
11
11
  'react-coding-style/react-memo-type-parameter': 'error',
12
12
  'react-coding-style/ban-use-imperative-handle-hook': 'error',
13
13
  'react-coding-style/use-memo-hook-style': 'error',
14
- 'react-coding-style/display-name': ['error', { ignoreTranspilerName: false }],
14
+ 'react-coding-style/display-name': ['error', {}],
15
15
  } as const satisfies EslintReactCodingStyleRules;
@@ -29,7 +29,7 @@ export const eslintReactRules = {
29
29
  /** Enforce consistent usage of props destructuring. */
30
30
  'react/destructuring-assignment': withDefaultOption('error'),
31
31
 
32
- 'react/display-name': withDefaultOption('error'),
32
+ 'react/display-name': 'off', // Covered by react-coding-style/display-name
33
33
  'react/forbid-component-props': ['error', { forbid: ['className'] }],
34
34
  'react/forbid-dom-props': withDefaultOption('error'),
35
35
  'react/forbid-elements': withDefaultOption('error'),
@@ -184,7 +184,8 @@ namespace BanUseImperativeHandleHook {
184
184
  }
185
185
 
186
186
  /**
187
- * Require displayName property for React components created with React.memo
187
+ * Require React.memo components to define displayName matching the component
188
+ * name
188
189
  *
189
190
  * ```md
190
191
  * | key | value |
@@ -202,9 +203,20 @@ namespace DisplayName {
202
203
  * {
203
204
  * "type": "object",
204
205
  * "properties": {
205
- * "ignoreTranspilerName": {
206
- * "type": "boolean",
207
- * "description": "When true, ignores components that get displayName from variable name"
206
+ * "ignoreName": {
207
+ * "description": "Component names allowed to have displayName different from the variable name.",
208
+ * "oneOf": [
209
+ * {
210
+ * "type": "string"
211
+ * },
212
+ * {
213
+ * "type": "array",
214
+ * "items": {
215
+ * "type": "string"
216
+ * },
217
+ * "minItems": 0
218
+ * }
219
+ * ]
208
220
  * }
209
221
  * },
210
222
  * "additionalProperties": false
@@ -213,8 +225,11 @@ namespace DisplayName {
213
225
  * ```
214
226
  */
215
227
  export type Options = Readonly<{
216
- /** When true, ignores components that get displayName from variable name */
217
- ignoreTranspilerName?: boolean;
228
+ /**
229
+ * Component names allowed to have displayName different from the variable
230
+ * name.
231
+ */
232
+ ignoreName?: string | readonly string[];
218
233
  }>;
219
234
 
220
235
  export type RuleEntry =