Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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‎

Lines changed: 33 additions & 0 deletions
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‎

Lines changed: 31 additions & 2 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /