diff --git a/docs/rules/no-object-as-default-parameter.md b/docs/rules/no-object-as-default-parameter.md index d1c66b2a03..e76d9b1043 100644 --- a/docs/rules/no-object-as-default-parameter.md +++ b/docs/rules/no-object-as-default-parameter.md @@ -2,13 +2,16 @@ Default parameters should not be passed to a function through an object literal. The `foo = {a: false}` parameter works fine if only used with one option. As soon as additional options are added, you risk replacing the whole `foo = {a: false, b: true}` object when passing only one option: `{a: true}`. For this reason, object destructuring should be used instead. - ## Fail ```js const abc = (foo = {a: false}) => {}; ``` +```js +function foo({a} = {a: false}) {} +``` + ```js const abc = (foo = {a: false, b: 123}) => {}; ``` @@ -20,6 +23,12 @@ const abc = (foo = {a: false, b: 123}) => {}; const abc = (foo = {}) => {}; ``` +```js +function foo(options) { + const {a} = {a: false, ...options}; +} +``` + ```js const abc = (foo = false) => {}; ``` diff --git a/rules/no-object-as-default-parameter.js b/rules/no-object-as-default-parameter.js index b8d3106f2c..8d4aef0891 100644 --- a/rules/no-object-as-default-parameter.js +++ b/rules/no-object-as-default-parameter.js @@ -1,13 +1,14 @@ 'use strict'; -const MESSAGE_ID = 'noObjectAsDefaultParameter'; +const MESSAGE_ID_IDENTIFIER = 'identifier'; +const MESSAGE_ID_NON_IDENTIFIER = 'non-identifier'; const messages = { - [MESSAGE_ID]: 'Do not use an object literal as default for parameter `{{parameter}}`.', + [MESSAGE_ID_IDENTIFIER]: 'Do not use an object literal as default for parameter `{{parameter}}`.', + [MESSAGE_ID_NON_IDENTIFIER]: 'Do not use an object literal as default.', }; const objectParameterSelector = [ ':function > AssignmentPattern.params', - '[left.type="Identifier"]', '[right.type="ObjectExpression"]', '[right.properties.length>0]', ].join(''); @@ -15,10 +16,19 @@ const objectParameterSelector = [ const create = () => { return { [objectParameterSelector]: node => { + const {left, right} = node; + + if (left.type === 'Identifier') { + return { + node: left, + messageId: MESSAGE_ID_IDENTIFIER, + data: {parameter: left.name}, + }; + } + return { - node: node.left, - messageId: MESSAGE_ID, - data: {parameter: node.left.name}, + node: right, + messageId: MESSAGE_ID_NON_IDENTIFIER, }; }, }; diff --git a/test/no-object-as-default-parameter.mjs b/test/no-object-as-default-parameter.mjs index f513f470e8..6461aa08d7 100644 --- a/test/no-object-as-default-parameter.mjs +++ b/test/no-object-as-default-parameter.mjs @@ -4,10 +4,14 @@ import {getTester} from './utils/test.mjs'; const {test} = getTester(import.meta); const error = { - messageId: 'noObjectAsDefaultParameter', + messageId: 'identifier', data: {parameter: 'foo'}, }; +const errorNonIdentifier = { + messageId: 'non-identifier', +}; + test({ valid: [ 'const abc = {};', @@ -160,6 +164,14 @@ test({ `, errors: [error], }, + { + code: outdent` + const A = class { + abc({a} = {a: 123}) {} + } + `, + errors: [errorNonIdentifier], + }, ], }); @@ -168,5 +180,7 @@ test.snapshot({ invalid: [ 'function abc(foo = {a: 123}) {}', 'const abc = (foo = {a: false}) => {};', + 'function abc({a} = {a: 123}) {}', + 'function abc([a] = {a: 123}) {}', ], }); diff --git a/test/snapshots/no-object-as-default-parameter.mjs.md b/test/snapshots/no-object-as-default-parameter.mjs.md index 810f7e13af..3ab30546f1 100644 --- a/test/snapshots/no-object-as-default-parameter.mjs.md +++ b/test/snapshots/no-object-as-default-parameter.mjs.md @@ -23,3 +23,23 @@ Generated by [AVA](https://avajs.dev). > 1 | const abc = (foo = {a: false}) => {};␊ | ^^^ Do not use an object literal as default for parameter \`foo\`.␊ ` + +## Invalid #3 + 1 | function abc({a} = {a: 123}) {} + +> Error 1/1 + + `␊ + > 1 | function abc({a} = {a: 123}) {}␊ + | ^^^^^^^^ Do not use an object literal as default.␊ + ` + +## Invalid #4 + 1 | function abc([a] = {a: 123}) {} + +> Error 1/1 + + `␊ + > 1 | function abc([a] = {a: 123}) {}␊ + | ^^^^^^^^ Do not use an object literal as default.␊ + ` diff --git a/test/snapshots/no-object-as-default-parameter.mjs.snap b/test/snapshots/no-object-as-default-parameter.mjs.snap index e1cefde508..2352ccdb5d 100644 Binary files a/test/snapshots/no-object-as-default-parameter.mjs.snap and b/test/snapshots/no-object-as-default-parameter.mjs.snap differ