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

Skip to content

Commit 2f0824b

Browse files
authored
feat(eslint-plugin): [prefer-optional-chain] added option to convert to suggestion fixer (typescript-eslint#1965)
1 parent 7f3fba3 commit 2f0824b

File tree

3 files changed

+117
-11
lines changed

3 files changed

+117
-11
lines changed

packages/eslint-plugin/docs/rules/prefer-optional-chain.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ foo?.a?.b?.method?.();
7070
foo?.a?.b?.c?.d?.e;
7171
```
7272

73+
## Options
74+
75+
The rule accepts an options object with the following properties:
76+
77+
```ts
78+
type Options = {
79+
// if true, the rule will only provide suggested fixes instead of automatically modifying code
80+
suggestInsteadOfAutofix?: boolean;
81+
};
82+
83+
const defaults = {
84+
suggestInsteadOfAutofix: false,
85+
};
86+
```
87+
7388
## When Not To Use It
7489

7590
If you are not using TypeScript 3.7 (or greater), then you will not be able to use this rule, as the operator is not supported.

packages/eslint-plugin/src/rules/prefer-optional-chain.ts

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
AST_NODE_TYPES,
33
TSESTree,
4+
TSESLint,
45
} from '@typescript-eslint/experimental-utils';
56
import * as util from '../util';
67

@@ -29,7 +30,16 @@ The AST will look like this:
2930
right: foo.bar.baz.buzz
3031
}
3132
*/
32-
export default util.createRule({
33+
34+
type Options = [
35+
{
36+
suggestInsteadOfAutofix?: boolean;
37+
},
38+
];
39+
40+
type MessageIds = 'preferOptionalChain' | 'optionalChainSuggest';
41+
42+
export default util.createRule<Options, MessageIds>({
3343
name: 'prefer-optional-chain',
3444
meta: {
3545
type: 'suggestion',
@@ -43,11 +53,26 @@ export default util.createRule({
4353
messages: {
4454
preferOptionalChain:
4555
"Prefer using an optional chain expression instead, as it's more concise and easier to read.",
56+
optionalChainSuggest: 'Change to an optional chain.',
4657
},
47-
schema: [],
58+
schema: [
59+
{
60+
type: 'object',
61+
properties: {
62+
suggestInsteadOfAutofix: {
63+
type: 'boolean',
64+
},
65+
},
66+
additionalProperties: false,
67+
},
68+
],
4869
},
49-
defaultOptions: [],
50-
create(context) {
70+
defaultOptions: [
71+
{
72+
suggestInsteadOfAutofix: false,
73+
},
74+
],
75+
create(context, [options]) {
5176
const sourceCode = context.getSourceCode();
5277
return {
5378
[[
@@ -163,13 +188,28 @@ export default util.createRule({
163188
} ${sourceCode.getText(previous.right.right)}`;
164189
}
165190

166-
context.report({
167-
node: previous,
168-
messageId: 'preferOptionalChain',
169-
fix(fixer) {
170-
return fixer.replaceText(previous, optionallyChainedCode);
171-
},
172-
});
191+
if (!options.suggestInsteadOfAutofix) {
192+
context.report({
193+
node: previous,
194+
messageId: 'preferOptionalChain',
195+
fix(fixer) {
196+
return fixer.replaceText(previous, optionallyChainedCode);
197+
},
198+
});
199+
} else {
200+
context.report({
201+
node: previous,
202+
messageId: 'preferOptionalChain',
203+
suggest: [
204+
{
205+
messageId: 'optionalChainSuggest',
206+
fix: (fixer): TSESLint.RuleFix[] => [
207+
fixer.replaceText(previous, optionallyChainedCode),
208+
],
209+
},
210+
],
211+
});
212+
}
173213
}
174214
},
175215
};

packages/eslint-plugin/tests/rules/prefer-optional-chain.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,5 +291,56 @@ ruleTester.run('prefer-optional-chain', rule, {
291291
},
292292
],
293293
},
294+
// using suggestion instead of autofix
295+
{
296+
code:
297+
'foo && foo.bar != null && foo.bar.baz !== undefined && foo.bar.baz.buzz;',
298+
options: [
299+
{
300+
suggestInsteadOfAutofix: true,
301+
},
302+
],
303+
output: null,
304+
errors: [
305+
{
306+
messageId: 'preferOptionalChain',
307+
line: 1,
308+
column: 1,
309+
suggestions: [
310+
{
311+
messageId: 'optionalChainSuggest',
312+
output: 'foo?.bar?.baz?.buzz;',
313+
},
314+
],
315+
},
316+
],
317+
},
318+
{
319+
code: 'foo && foo.bar(baz => <This Requires Spaces />);',
320+
options: [
321+
{
322+
suggestInsteadOfAutofix: true,
323+
},
324+
],
325+
output: null,
326+
errors: [
327+
{
328+
messageId: 'preferOptionalChain',
329+
line: 1,
330+
column: 1,
331+
suggestions: [
332+
{
333+
messageId: 'optionalChainSuggest',
334+
output: 'foo?.bar(baz => <This Requires Spaces />);',
335+
},
336+
],
337+
},
338+
],
339+
parserOptions: {
340+
ecmaFeatures: {
341+
jsx: true,
342+
},
343+
},
344+
},
294345
],
295346
});

0 commit comments

Comments
 (0)