diff --git a/lib/rules/max-props.js b/lib/rules/max-props.js
index 698757e78..0dc3043bf 100644
--- a/lib/rules/max-props.js
+++ b/lib/rules/max-props.js
@@ -39,14 +39,17 @@ module.exports = {
/**
* @param {import('../utils').ComponentProp[]} props
+ * @param {CallExpression | Property} node
*/
- function checkMaxNumberOfProps(props) {
- if (props.length > option.maxProps && props[0].node) {
+ function checkMaxNumberOfProps(props, node) {
+ const uniqueProps = new Set(props.map((prop) => prop.propName))
+ const propCount = uniqueProps.size
+ if (propCount > option.maxProps && props[0].node) {
context.report({
- node: props[0].node.parent,
+ node,
messageId: 'tooManyProps',
data: {
- propCount: props.length,
+ propCount,
limit: option.maxProps
}
})
@@ -54,12 +57,23 @@ module.exports = {
}
return utils.compositingVisitors(
- utils.executeOnVue(context, (obj) => {
- checkMaxNumberOfProps(utils.getComponentPropsFromOptions(obj))
+ utils.executeOnVue(context, (node) => {
+ const propsNode = node.properties.find(
+ /** @returns {p is Property} */
+ (p) =>
+ p.type === 'Property' && utils.getStaticPropertyName(p) === 'props'
+ )
+
+ if (!propsNode) return
+
+ checkMaxNumberOfProps(
+ utils.getComponentPropsFromOptions(node),
+ propsNode
+ )
}),
utils.defineScriptSetupVisitor(context, {
- onDefinePropsEnter(_, props) {
- checkMaxNumberOfProps(props)
+ onDefinePropsEnter(node, props) {
+ checkMaxNumberOfProps(props, node)
}
})
)
diff --git a/tests/lib/rules/max-props.js b/tests/lib/rules/max-props.js
index 1ebfb9cff..7d000f363 100644
--- a/tests/lib/rules/max-props.js
+++ b/tests/lib/rules/max-props.js
@@ -26,6 +26,15 @@ tester.run('max-props', rule, {
`,
options: [{ maxProps: 5 }]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ options: [{ maxProps: 5 }]
+ },
{
filename: 'test.vue',
code: `
@@ -99,6 +108,20 @@ tester.run('max-props', rule, {
parser: require.resolve('@typescript-eslint/parser')
}
}
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ options: [{ maxProps: 2 }],
+ languageOptions: {
+ parserOptions: {
+ parser: require.resolve('@typescript-eslint/parser')
+ }
+ }
}
],
invalid: [
@@ -160,6 +183,56 @@ tester.run('max-props', rule, {
endLine: 3
}
]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ options: [{ maxProps: 2 }],
+ languageOptions: {
+ parserOptions: {
+ parser: require.resolve('@typescript-eslint/parser')
+ }
+ },
+ errors: [
+ {
+ message: 'Component has too many props (3). Maximum allowed is 2.',
+ line: 3,
+ endLine: 3
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `,
+ options: [{ maxProps: 2 }],
+ languageOptions: {
+ parserOptions: {
+ parser: require.resolve('@typescript-eslint/parser')
+ }
+ },
+ errors: [
+ {
+ message: 'Component has too many props (3). Maximum allowed is 2.',
+ line: 3,
+ endLine: 11
+ }
+ ]
}
]
})