Skip to content

Commit 4c38983

Browse files
authored
Add support for props destructure to vue/no-restricted-props rule (#2562)
1 parent 3137e50 commit 4c38983

File tree

2 files changed

+92
-15
lines changed

2 files changed

+92
-15
lines changed

lib/rules/no-restricted-props.js

+41-14
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ module.exports = {
9595

9696
/**
9797
* @param {ComponentProp[]} props
98-
* @param { { [key: string]: Property | undefined } } [withDefaultsProps]
98+
* @param {(fixer: RuleFixer, propName: string, replaceKeyText: string) => Iterable<Fix>} [fixPropInOtherPlaces]
9999
*/
100-
function processProps(props, withDefaultsProps) {
100+
function processProps(props, fixPropInOtherPlaces) {
101101
for (const prop of props) {
102102
if (!prop.propName) {
103103
continue
@@ -118,7 +118,14 @@ module.exports = {
118118
: createSuggest(
119119
prop.key,
120120
option,
121-
withDefaultsProps && withDefaultsProps[prop.propName]
121+
fixPropInOtherPlaces
122+
? (fixer, replaceKeyText) =>
123+
fixPropInOtherPlaces(
124+
fixer,
125+
prop.propName,
126+
replaceKeyText
127+
)
128+
: undefined
122129
)
123130
})
124131
break
@@ -129,7 +136,33 @@ module.exports = {
129136
return utils.compositingVisitors(
130137
utils.defineScriptSetupVisitor(context, {
131138
onDefinePropsEnter(node, props) {
132-
processProps(props, utils.getWithDefaultsProps(node))
139+
processProps(props, fixPropInOtherPlaces)
140+
141+
/**
142+
* @param {RuleFixer} fixer
143+
* @param {string} propName
144+
* @param {string} replaceKeyText
145+
*/
146+
function fixPropInOtherPlaces(fixer, propName, replaceKeyText) {
147+
/** @type {(Property|AssignmentProperty)[]} */
148+
const propertyNodes = []
149+
const withDefault = utils.getWithDefaultsProps(node)[propName]
150+
if (withDefault) {
151+
propertyNodes.push(withDefault)
152+
}
153+
const propDestructure = utils.getPropsDestructure(node)[propName]
154+
if (propDestructure) {
155+
propertyNodes.push(propDestructure)
156+
}
157+
return propertyNodes.map((propertyNode) =>
158+
propertyNode.shorthand
159+
? fixer.insertTextBefore(
160+
propertyNode.value,
161+
`${replaceKeyText}:`
162+
)
163+
: fixer.replaceText(propertyNode.key, replaceKeyText)
164+
)
165+
}
133166
}
134167
}),
135168
utils.defineVueVisitor(context, {
@@ -144,10 +177,10 @@ module.exports = {
144177
/**
145178
* @param {Expression} node
146179
* @param {ParsedOption} option
147-
* @param {Property} [withDefault]
180+
* @param {(fixer: RuleFixer, replaceKeyText: string) => Iterable<Fix>} [fixPropInOtherPlaces]
148181
* @returns {Rule.SuggestionReportDescriptor[]}
149182
*/
150-
function createSuggest(node, option, withDefault) {
183+
function createSuggest(node, option, fixPropInOtherPlaces) {
151184
if (!option.suggest) {
152185
return []
153186
}
@@ -168,14 +201,8 @@ function createSuggest(node, option, withDefault) {
168201
{
169202
fix(fixer) {
170203
const fixes = [fixer.replaceText(node, replaceText)]
171-
if (withDefault) {
172-
if (withDefault.shorthand) {
173-
fixes.push(
174-
fixer.insertTextBefore(withDefault.value, `${replaceText}:`)
175-
)
176-
} else {
177-
fixes.push(fixer.replaceText(withDefault.key, replaceText))
178-
}
204+
if (fixPropInOtherPlaces) {
205+
fixes.push(...fixPropInOtherPlaces(fixer, replaceText))
179206
}
180207
return fixes.sort((a, b) => a.range[0] - b.range[0])
181208
},

tests/lib/rules/no-restricted-props.js

+51-1
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,56 @@ tester.run('no-restricted-props', rule, {
611611
}
612612
]
613613
}
614-
])
614+
]),
615+
{
616+
filename: 'test.vue',
617+
code: `
618+
<script setup>
619+
const {foo=false} = defineProps({foo:Boolean})
620+
</script>
621+
`,
622+
options: [{ name: 'foo', suggest: 'Foo' }],
623+
errors: [
624+
{
625+
message: 'Using `foo` props is not allowed.',
626+
line: 3,
627+
suggestions: [
628+
{
629+
desc: 'Instead, change to `Foo`.',
630+
output: `
631+
<script setup>
632+
const {Foo:foo=false} = defineProps({Foo:Boolean})
633+
</script>
634+
`
635+
}
636+
]
637+
}
638+
]
639+
},
640+
{
641+
filename: 'test.vue',
642+
code: `
643+
<script setup>
644+
const {foo:bar=false} = defineProps({foo:Boolean})
645+
</script>
646+
`,
647+
options: [{ name: 'foo', suggest: 'Foo' }],
648+
errors: [
649+
{
650+
message: 'Using `foo` props is not allowed.',
651+
line: 3,
652+
suggestions: [
653+
{
654+
desc: 'Instead, change to `Foo`.',
655+
output: `
656+
<script setup>
657+
const {Foo:bar=false} = defineProps({Foo:Boolean})
658+
</script>
659+
`
660+
}
661+
]
662+
}
663+
]
664+
}
615665
]
616666
})

0 commit comments

Comments
 (0)