Skip to content

Commit 7dec48d

Browse files
authored
fix(no-dupe-keys): detect props destructure rename (#2731)
1 parent 41e0192 commit 7dec48d

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

lib/rules/no-dupe-keys.js

+33
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,33 @@ function isInsideInitializer(node, references) {
5858
)
5959
}
6060

61+
/**
62+
* Collects all renamed props from a pattern
63+
* @param {Pattern | null} pattern - The destructuring pattern
64+
* @returns {Set<string>} - Set of prop names that have been renamed
65+
*/
66+
function collectRenamedProps(pattern) {
67+
const renamedProps = new Set()
68+
69+
if (!pattern || pattern.type !== 'ObjectPattern') {
70+
return renamedProps
71+
}
72+
73+
for (const prop of pattern.properties) {
74+
if (prop.type !== 'Property') continue
75+
76+
if (
77+
prop.key.type === 'Identifier' &&
78+
prop.value.type === 'Identifier' &&
79+
prop.key.name !== prop.value.name
80+
) {
81+
renamedProps.add(prop.key.name)
82+
}
83+
}
84+
85+
return renamedProps
86+
}
87+
6188
module.exports = {
6289
meta: {
6390
type: 'problem',
@@ -115,9 +142,15 @@ module.exports = {
115142
node
116143
]
117144

145+
const renamedProps = collectRenamedProps(propsNode)
146+
118147
for (const prop of props) {
119148
if (!prop.propName) continue
120149

150+
if (renamedProps.has(prop.propName)) {
151+
continue
152+
}
153+
121154
const variable = findVariable(
122155
utils.getScope(context, node),
123156
prop.propName

tests/lib/rules/no-dupe-keys.js

+31-2
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ ruleTester.run('no-dupe-keys', rule, {
466466
{
467467
filename: 'test.vue',
468468
code: `
469-
<script setup></script>
469+
<script setup>
470470
const {foo,bar} = defineProps(['foo', 'bar'])
471471
</script>
472472
`,
@@ -475,7 +475,7 @@ ruleTester.run('no-dupe-keys', rule, {
475475
{
476476
filename: 'test.vue',
477477
code: `
478-
<script setup></script>
478+
<script setup>
479479
const {foo=42,bar='abc'} = defineProps(['foo', 'bar'])
480480
</script>
481481
`,
@@ -500,6 +500,17 @@ ruleTester.run('no-dupe-keys', rule, {
500500
parser: require('vue-eslint-parser'),
501501
parserOptions: { parser: require.resolve('@typescript-eslint/parser') }
502502
}
503+
},
504+
{
505+
filename: 'test.vue',
506+
code: `
507+
<script setup>
508+
const { foo: renamedFoo, bar: renamedBar } = defineProps(['foo', 'bar'])
509+
const foo = 42
510+
const bar = 'hello'
511+
</script>
512+
`,
513+
languageOptions: { parser: require('vue-eslint-parser') }
503514
}
504515
],
505516

@@ -1105,6 +1116,24 @@ ruleTester.run('no-dupe-keys', rule, {
11051116
line: 5
11061117
}
11071118
]
1119+
},
1120+
{
1121+
filename: 'test.vue',
1122+
code: `
1123+
<script setup>
1124+
const { foo: renamedFoo } = defineProps(['foo', 'bar'])
1125+
const foo = 'foo'
1126+
const bar = 'bar'
1127+
</script>
1128+
`,
1129+
languageOptions: { parser: require('vue-eslint-parser') },
1130+
errors: [
1131+
{
1132+
message:
1133+
"Duplicate key 'bar'. May cause name collision in script or template tag.",
1134+
line: 5
1135+
}
1136+
]
11081137
}
11091138
]
11101139
})

0 commit comments

Comments
 (0)