diff --git a/lib/rules/no-boolean-default.js b/lib/rules/no-boolean-default.js
index 6796c0329..2ff6a2d06 100644
--- a/lib/rules/no-boolean-default.js
+++ b/lib/rules/no-boolean-default.js
@@ -8,18 +8,27 @@ const utils = require('../utils')
/**
* @typedef {import('../utils').ComponentProp} ComponentProp
+ * @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
*/
/**
- * @param {Property | SpreadElement} prop
+ * @param {Expression|undefined} node
+ */
+function isBooleanIdentifier(node) {
+ return Boolean(node && node.type === 'Identifier' && node.name === 'Boolean')
+}
+
+/**
+ * Detects whether given prop node is a Boolean
+ * @param {ComponentObjectProp} prop
+ * @return {Boolean}
*/
function isBooleanProp(prop) {
+ const value = utils.skipTSAsExpression(prop.value)
return (
- prop.type === 'Property' &&
- prop.key.type === 'Identifier' &&
- prop.key.name === 'type' &&
- prop.value.type === 'Identifier' &&
- prop.value.name === 'Boolean'
+ isBooleanIdentifier(value) ||
+ (value.type === 'ObjectExpression' &&
+ isBooleanIdentifier(utils.findProperty(value, 'type')?.value))
)
}
@@ -55,40 +64,40 @@ module.exports = {
const booleanType = context.options[0] || 'no-default'
/**
* @param {ComponentProp} prop
- * @param { { [key: string]: Expression | undefined } } [withDefaultsExpressions]
+ * @param {(propName: string) => Expression[]} otherDefaultProvider
*/
- function processProp(prop, withDefaultsExpressions) {
+ function processProp(prop, otherDefaultProvider) {
if (prop.type === 'object') {
- if (prop.value.type !== 'ObjectExpression') {
+ if (!isBooleanProp(prop)) {
return
}
- if (!prop.value.properties.some(isBooleanProp)) {
- return
+ if (prop.value.type === 'ObjectExpression') {
+ const defaultNode = getDefaultNode(prop.value)
+ if (defaultNode) {
+ verifyDefaultExpression(defaultNode.value)
+ }
}
- const defaultNode = getDefaultNode(prop.value)
- if (!defaultNode) {
- return
+ if (prop.propName != null) {
+ for (const defaultNode of otherDefaultProvider(prop.propName)) {
+ verifyDefaultExpression(defaultNode)
+ }
}
- verifyDefaultExpression(defaultNode.value)
} else if (prop.type === 'type') {
if (prop.types.length !== 1 || prop.types[0] !== 'Boolean') {
return
}
- const defaultNode =
- withDefaultsExpressions && withDefaultsExpressions[prop.propName]
- if (!defaultNode) {
- return
+ for (const defaultNode of otherDefaultProvider(prop.propName)) {
+ verifyDefaultExpression(defaultNode)
}
- verifyDefaultExpression(defaultNode)
}
}
/**
* @param {ComponentProp[]} props
- * @param { { [key: string]: Expression | undefined } } [withDefaultsExpressions]
+ * @param {(propName: string) => Expression[]} otherDefaultProvider
*/
- function processProps(props, withDefaultsExpressions) {
+ function processProps(props, otherDefaultProvider) {
for (const prop of props) {
- processProp(prop, withDefaultsExpressions)
+ processProp(prop, otherDefaultProvider)
}
}
@@ -118,11 +127,20 @@ module.exports = {
}
return utils.compositingVisitors(
utils.executeOnVueComponent(context, (obj) => {
- processProps(utils.getComponentPropsFromOptions(obj))
+ processProps(utils.getComponentPropsFromOptions(obj), () => [])
}),
utils.defineScriptSetupVisitor(context, {
onDefinePropsEnter(node, props) {
- processProps(props, utils.getWithDefaultsPropExpressions(node))
+ const defaultsByWithDefaults =
+ utils.getWithDefaultsPropExpressions(node)
+ const defaultsByAssignmentPatterns =
+ utils.getDefaultPropExpressionsForPropsDestructure(node)
+ processProps(props, (propName) =>
+ [
+ defaultsByWithDefaults[propName],
+ defaultsByAssignmentPatterns[propName]?.expression
+ ].filter(utils.isDef)
+ )
}
})
)
diff --git a/tests/lib/rules/no-boolean-default.js b/tests/lib/rules/no-boolean-default.js
index 6f275c671..98524760c 100644
--- a/tests/lib/rules/no-boolean-default.js
+++ b/tests/lib/rules/no-boolean-default.js
@@ -326,6 +326,18 @@ ruleTester.run('no-boolean-default', rule, {
parser: require.resolve('@typescript-eslint/parser')
}
}
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ options: ['default-false'],
+ languageOptions: {
+ parser: require('vue-eslint-parser')
+ }
}
],
@@ -512,6 +524,42 @@ ruleTester.run('no-boolean-default', rule, {
}
]
}
- ])
+ ]),
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ languageOptions: {
+ parser: require('vue-eslint-parser')
+ },
+ errors: [
+ {
+ message:
+ 'Boolean prop should not set a default (Vue defaults it to false).',
+ line: 3
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ options: ['default-false'],
+ languageOptions: {
+ parser: require('vue-eslint-parser')
+ },
+ errors: [
+ {
+ message: 'Boolean prop should only be defaulted to false.',
+ line: 3
+ }
+ ]
+ }
]
})