Skip to content

Commit 4aa7d60

Browse files
authored
no-useless-undefined: Turn parameter with undefined default value into optional parameter (#2138)
1 parent 7b473aa commit 4aa7d60

File tree

4 files changed

+313
-2
lines changed

4 files changed

+313
-2
lines changed

rules/no-useless-undefined.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
const {isCommaToken} = require('@eslint-community/eslint-utils');
33
const {replaceNodeOrTokenAndSpacesBefore} = require('./fix/index.js');
4-
const {isUndefined} = require('./ast/index.js');
4+
const {isUndefined, isFunction} = require('./ast/index.js');
55

66
const messageId = 'no-useless-undefined';
77
const messages = {
@@ -80,6 +80,9 @@ const isFunctionBindCall = node =>
8080
&& node.callee.property.type === 'Identifier'
8181
&& node.callee.property.name === 'bind';
8282

83+
const isTypeScriptFile = context =>
84+
/\.(?:ts|mts|cts|tsx)$/i.test(context.getPhysicalFilename());
85+
8386
/** @param {import('eslint').Rule.RuleContext} context */
8487
const create = context => {
8588
const {sourceCode} = context;
@@ -179,7 +182,24 @@ const create = context => {
179182
) {
180183
return getProblem(
181184
node,
182-
fixer => fixer.removeRange([node.parent.left.range[1], node.range[1]]),
185+
function * (fixer) {
186+
const assignmentPattern = node.parent;
187+
const {left} = assignmentPattern;
188+
189+
yield fixer.removeRange([left.range[1], node.range[1]]);
190+
if (
191+
(left.typeAnnotation || isTypeScriptFile(context))
192+
&& !left.optional
193+
&& isFunction(assignmentPattern.parent)
194+
&& assignmentPattern.parent.params.includes(assignmentPattern)
195+
) {
196+
yield (
197+
left.typeAnnotation
198+
? fixer.insertTextBefore(left.typeAnnotation, '?')
199+
: fixer.insertTextAfter(left, '?')
200+
);
201+
}
202+
},
183203
/* CheckFunctionReturnType */ true,
184204
);
185205
}

test/no-useless-undefined.mjs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,34 @@ test.snapshot({
471471
`,
472472
],
473473
});
474+
475+
test.snapshot({
476+
testerOptions: {
477+
parser: parsers.typescript,
478+
},
479+
valid: [],
480+
invalid: [
481+
'function f(foo: Type = undefined) {}',
482+
'function f(foo?: Type = undefined) {}',
483+
'const f = function(foo: Type = undefined) {}',
484+
'const f = (foo: Type = undefined) => {}',
485+
'const f = {method(foo: Type = undefined){}}',
486+
'const f = class {method(foo: Type = undefined){}}',
487+
'function f(foo = undefined) {}',
488+
...[
489+
undefined,
490+
'foo.js',
491+
'foo.ts',
492+
'foo.MTs',
493+
'foo.cts',
494+
'foo.tsx',
495+
].map(filename => ({
496+
code: 'function f(foo = undefined) {}',
497+
filename,
498+
})),
499+
{
500+
code: 'function a({foo} = undefined) {}',
501+
filename: 'foo.ts',
502+
},
503+
],
504+
});

test/snapshots/no-useless-undefined.mjs.md

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,263 @@ Generated by [AVA](https://avajs.dev).
324324
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
325325
4 | </script>␊
326326
`
327+
328+
## Invalid #1
329+
1 | function f(foo: Type = undefined) {}
330+
331+
> Output
332+
333+
`␊
334+
1 | function f(foo?: Type) {}␊
335+
`
336+
337+
> Error 1/1
338+
339+
`␊
340+
> 1 | function f(foo: Type = undefined) {}␊
341+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
342+
`
343+
344+
## Invalid #2
345+
1 | function f(foo?: Type = undefined) {}
346+
347+
> Output
348+
349+
`␊
350+
1 | function f(foo?: Type) {}␊
351+
`
352+
353+
> Error 1/1
354+
355+
`␊
356+
> 1 | function f(foo?: Type = undefined) {}␊
357+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
358+
`
359+
360+
## Invalid #3
361+
1 | const f = function(foo: Type = undefined) {}
362+
363+
> Output
364+
365+
`␊
366+
1 | const f = function(foo?: Type) {}␊
367+
`
368+
369+
> Error 1/1
370+
371+
`␊
372+
> 1 | const f = function(foo: Type = undefined) {}␊
373+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
374+
`
375+
376+
## Invalid #4
377+
1 | const f = (foo: Type = undefined) => {}
378+
379+
> Output
380+
381+
`␊
382+
1 | const f = (foo?: Type) => {}␊
383+
`
384+
385+
> Error 1/1
386+
387+
`␊
388+
> 1 | const f = (foo: Type = undefined) => {}␊
389+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
390+
`
391+
392+
## Invalid #5
393+
1 | const f = {method(foo: Type = undefined){}}
394+
395+
> Output
396+
397+
`␊
398+
1 | const f = {method(foo?: Type){}}␊
399+
`
400+
401+
> Error 1/1
402+
403+
`␊
404+
> 1 | const f = {method(foo: Type = undefined){}}␊
405+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
406+
`
407+
408+
## Invalid #6
409+
1 | const f = class {method(foo: Type = undefined){}}
410+
411+
> Output
412+
413+
`␊
414+
1 | const f = class {method(foo?: Type){}}␊
415+
`
416+
417+
> Error 1/1
418+
419+
`␊
420+
> 1 | const f = class {method(foo: Type = undefined){}}␊
421+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
422+
`
423+
424+
## Invalid #7
425+
1 | function f(foo = undefined) {}
426+
427+
> Output
428+
429+
`␊
430+
1 | function f(foo) {}␊
431+
`
432+
433+
> Error 1/1
434+
435+
`␊
436+
> 1 | function f(foo = undefined) {}␊
437+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
438+
`
439+
440+
## Invalid #8
441+
1 | function f(foo = undefined) {}
442+
443+
> Output
444+
445+
`␊
446+
1 | function f(foo) {}␊
447+
`
448+
449+
> Error 1/1
450+
451+
`␊
452+
> 1 | function f(foo = undefined) {}␊
453+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
454+
`
455+
456+
## Invalid #9
457+
1 | function f(foo = undefined) {}
458+
459+
> Filename
460+
461+
`␊
462+
foo.js␊
463+
`
464+
465+
> Output
466+
467+
`␊
468+
1 | function f(foo) {}␊
469+
`
470+
471+
> Error 1/1
472+
473+
`␊
474+
> 1 | function f(foo = undefined) {}␊
475+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
476+
`
477+
478+
## Invalid #10
479+
1 | function f(foo = undefined) {}
480+
481+
> Filename
482+
483+
`␊
484+
foo.ts␊
485+
`
486+
487+
> Output
488+
489+
`␊
490+
1 | function f(foo?) {}␊
491+
`
492+
493+
> Error 1/1
494+
495+
`␊
496+
> 1 | function f(foo = undefined) {}␊
497+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
498+
`
499+
500+
## Invalid #11
501+
1 | function f(foo = undefined) {}
502+
503+
> Filename
504+
505+
`␊
506+
foo.MTs␊
507+
`
508+
509+
> Output
510+
511+
`␊
512+
1 | function f(foo?) {}␊
513+
`
514+
515+
> Error 1/1
516+
517+
`␊
518+
> 1 | function f(foo = undefined) {}␊
519+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
520+
`
521+
522+
## Invalid #12
523+
1 | function f(foo = undefined) {}
524+
525+
> Filename
526+
527+
`␊
528+
foo.cts␊
529+
`
530+
531+
> Output
532+
533+
`␊
534+
1 | function f(foo?) {}␊
535+
`
536+
537+
> Error 1/1
538+
539+
`␊
540+
> 1 | function f(foo = undefined) {}␊
541+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
542+
`
543+
544+
## Invalid #13
545+
1 | function f(foo = undefined) {}
546+
547+
> Filename
548+
549+
`␊
550+
foo.tsx␊
551+
`
552+
553+
> Output
554+
555+
`␊
556+
1 | function f(foo?) {}␊
557+
`
558+
559+
> Error 1/1
560+
561+
`␊
562+
> 1 | function f(foo = undefined) {}␊
563+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
564+
`
565+
566+
## Invalid #14
567+
1 | function a({foo} = undefined) {}
568+
569+
> Filename
570+
571+
`␊
572+
foo.ts␊
573+
`
574+
575+
> Output
576+
577+
`␊
578+
1 | function a({foo}?) {}␊
579+
`
580+
581+
> Error 1/1
582+
583+
`␊
584+
> 1 | function a({foo} = undefined) {}␊
585+
| ^^^^^^^^^ Do not use useless \`undefined\`.␊
586+
`
614 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)