Skip to content

Commit

Permalink
fix(max-props): count unique keys (#2683)
Browse files Browse the repository at this point in the history
  • Loading branch information
waynzh authored Feb 12, 2025
1 parent 487af10 commit 827ab4b
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 8 deletions.
30 changes: 22 additions & 8 deletions lib/rules/max-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,41 @@ 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
}
})
}
}

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)
}
})
)
Expand Down
73 changes: 73 additions & 0 deletions tests/lib/rules/max-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ tester.run('max-props', rule, {
`,
options: [{ maxProps: 5 }]
},
{
filename: 'test.vue',
code: `
<script setup>
defineProps(['prop1', 'prop2'])
</script>
`,
options: [{ maxProps: 5 }]
},
{
filename: 'test.vue',
code: `
Expand Down Expand Up @@ -99,6 +108,20 @@ tester.run('max-props', rule, {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: `
<script setup lang="ts">
defineProps<{prop1: string, prop2: string} | {prop1: number}>()
</script>
`,
options: [{ maxProps: 2 }],
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
}
],
invalid: [
Expand Down Expand Up @@ -160,6 +183,56 @@ tester.run('max-props', rule, {
endLine: 3
}
]
},
{
filename: 'test.vue',
code: `
<script setup lang="ts">
defineProps<{prop1: string, prop2: string} | {prop1: number, prop3: string}>()
</script>
`,
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: `
<script setup lang="ts">
defineProps<{
prop1: string
} & {
prop2?: true;
prop3?: never;
} | {
prop2?: false;
prop3?: boolean;
}>()
</script>
`,
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
}
]
}
]
})

0 comments on commit 827ab4b

Please sign in to comment.