diff --git a/lib/rules/no-unused-properties.js b/lib/rules/no-unused-properties.js
index be18224ed..9a38c2a75 100644
--- a/lib/rules/no-unused-properties.js
+++ b/lib/rules/no-unused-properties.js
@@ -12,9 +12,27 @@ const utils = require('../utils')
const eslintUtils = require('eslint-utils')
/**
- * @typedef {import('../utils').ComponentPropertyData} ComponentPropertyData
+ * @typedef {import('../utils').GroupName} GroupName
* @typedef {import('../utils').VueObjectData} VueObjectData
*/
+
+/**
+ * @typedef {object} ComponentObjectPropertyData
+ * @property {string} name
+ * @property {GroupName} groupName
+ * @property {'object'} type
+ * @property {ASTNode} node
+ * @property {Property} property
+ *
+ * @typedef {object} ComponentNonObjectPropertyData
+ * @property {string} name
+ * @property {GroupName} groupName
+ * @property {'array' | 'type'} type
+ * @property {ASTNode} node
+ *
+ * @typedef { ComponentNonObjectPropertyData | ComponentObjectPropertyData } ComponentPropertyData
+ */
+
/**
* @typedef {object} TemplatePropertiesContainer
* @property {UsedProperties} usedProperties
@@ -256,7 +274,7 @@ class ParamsUsedProperties {
return param
}
if (this.node.params[index]) {
- return (this.params[index] = extractParamProperties(
+ return (this.params[index] = extractParamOrVerProperties(
this.node.params[index],
this.context
))
@@ -270,7 +288,7 @@ class ParamsUsedProperties {
* @param {RuleContext} context
* @returns {UsedProperties}
*/
-function extractParamProperties(node, context) {
+function extractParamOrVerProperties(node, context) {
const result = new UsedProperties()
while (node.type === 'AssignmentPattern') {
@@ -826,7 +844,58 @@ module.exports = {
}
const scriptVisitor = utils.compositingVisitors(
- {},
+ utils.defineScriptSetupVisitor(context, {
+ onDefinePropsEnter(node, props) {
+ if (!groups.has('props')) {
+ return
+ }
+ const container = getVueComponentPropertiesContainer(node)
+
+ for (const prop of props) {
+ if (!prop.propName) {
+ continue
+ }
+ if (prop.type === 'object') {
+ container.properties.push({
+ type: prop.type,
+ name: prop.propName,
+ groupName: 'props',
+ node: prop.key,
+ property: prop.node
+ })
+ } else {
+ container.properties.push({
+ type: prop.type,
+ name: prop.propName,
+ groupName: 'props',
+ node: prop.key
+ })
+ }
+ }
+ let target = node
+ if (
+ target.parent &&
+ target.parent.type === 'CallExpression' &&
+ target.parent.arguments[0] === target &&
+ target.parent.callee.type === 'Identifier' &&
+ target.parent.callee.name === 'withDefaults'
+ ) {
+ target = target.parent
+ }
+
+ if (
+ !target.parent ||
+ target.parent.type !== 'VariableDeclarator' ||
+ target.parent.init !== target
+ ) {
+ return
+ }
+
+ const pattern = target.parent.id
+ const usedProps = extractParamOrVerProperties(pattern, context)
+ container.usedPropertiesForProps.merge(usedProps)
+ }
+ }),
utils.defineVueVisitor(context, {
onVueObjectEnter(node) {
const container = getVueComponentPropertiesContainer(node)
diff --git a/tests/lib/rules/no-unused-properties.js b/tests/lib/rules/no-unused-properties.js
index e52a4bbf4..f9d61e4b0 100644
--- a/tests/lib/rules/no-unused-properties.js
+++ b/tests/lib/rules/no-unused-properties.js
@@ -2400,6 +2400,18 @@ tester.run('no-unused-properties', rule, {
"'a' of data found, but never used.",
"'b' of data found, but never used."
]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ {{a}}
+
+ `,
+ errors: ["'c' of property found, but never used."]
}
]
})