Skip to content

Commit ec5fdad

Browse files
committed
Update vue/require-prop-type-constructor rule to support <script setup>
1 parent 11b2077 commit ec5fdad

File tree

3 files changed

+84
-36
lines changed

3 files changed

+84
-36
lines changed

Diff for: lib/rules/require-prop-type-constructor.js

+20-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
const utils = require('../utils')
88
const { isDef } = require('../utils')
99

10+
/**
11+
* @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp
12+
* @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp
13+
*/
14+
1015
// ------------------------------------------------------------------------------
1116
// Rule Definition
1217
// ------------------------------------------------------------------------------
@@ -76,8 +81,9 @@ module.exports = {
7681
)
7782
}
7883

79-
return utils.executeOnVueComponent(context, (obj) => {
80-
for (const prop of utils.getComponentProps(obj)) {
84+
/** @param {(ComponentArrayProp | ComponentObjectProp)[]} props */
85+
function verifyProps(props) {
86+
for (const prop of props) {
8187
if (!prop.value || prop.propName == null) {
8288
continue
8389
}
@@ -94,6 +100,17 @@ module.exports = {
94100
checkPropertyNode(prop.propName, typeProperty.value)
95101
}
96102
}
97-
})
103+
}
104+
105+
return utils.compositingVisitors(
106+
utils.defineScriptSetupVisitor(context, {
107+
onDefinePropsEnter(_node, props) {
108+
verifyProps(props)
109+
}
110+
}),
111+
utils.executeOnVueComponent(context, (obj) => {
112+
verifyProps(utils.getComponentProps(obj))
113+
})
114+
)
98115
}
99116
}

Diff for: lib/utils/index.js

+34-33
Original file line numberDiff line numberDiff line change
@@ -1097,42 +1097,43 @@ module.exports = {
10971097
return null
10981098
}
10991099

1100-
const definePropsMap = new Map()
1101-
/**
1102-
* @param {CallExpression} node
1103-
*/
1104-
scriptSetupVisitor.CallExpression = (node) => {
1105-
if (
1106-
inScriptSetup(node) &&
1107-
node.callee.type === 'Identifier' &&
1108-
node.callee.name === 'defineProps'
1109-
) {
1110-
/** @type {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} */
1111-
let props = []
1112-
if (node.arguments.length >= 1) {
1113-
const defNode = getObjectOrArray(node.arguments[0])
1114-
if (defNode) {
1115-
props = getComponentPropsFromDefine(defNode)
1116-
}
1117-
} else if (
1118-
node.typeParameters &&
1119-
node.typeParameters.params.length >= 1
1100+
if (visitor.onDefinePropsEnter || visitor.onDefinePropsExit) {
1101+
const definePropsMap = new Map()
1102+
/**
1103+
* @param {CallExpression} node
1104+
*/
1105+
scriptSetupVisitor.CallExpression = (node) => {
1106+
if (
1107+
inScriptSetup(node) &&
1108+
node.callee.type === 'Identifier' &&
1109+
node.callee.name === 'defineProps'
11201110
) {
1121-
props = getComponentPropsFromTypeDefine(
1122-
context,
1123-
node.typeParameters.params[0]
1124-
)
1111+
/** @type {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} */
1112+
let props = []
1113+
if (node.arguments.length >= 1) {
1114+
const defNode = getObjectOrArray(node.arguments[0])
1115+
if (defNode) {
1116+
props = getComponentPropsFromDefine(defNode)
1117+
}
1118+
} else if (
1119+
node.typeParameters &&
1120+
node.typeParameters.params.length >= 1
1121+
) {
1122+
props = getComponentPropsFromTypeDefine(
1123+
context,
1124+
node.typeParameters.params[0]
1125+
)
1126+
}
1127+
callVisitor('onDefinePropsEnter', node, props)
11251128
}
1126-
definePropsMap.set(node, props)
1127-
callVisitor('onDefinePropsEnter', node, props)
1129+
callVisitor('CallExpression', node)
11281130
}
1129-
callVisitor('CallExpression', node)
1130-
}
1131-
scriptSetupVisitor['CallExpression:exit'] = (node) => {
1132-
callVisitor('CallExpression:exit', node)
1133-
if (definePropsMap.has(node)) {
1134-
callVisitor('onDefinePropsExit', node, definePropsMap.get(node))
1135-
definePropsMap.delete(node)
1131+
scriptSetupVisitor['CallExpression:exit'] = (node) => {
1132+
callVisitor('CallExpression:exit', node)
1133+
if (definePropsMap.has(node)) {
1134+
callVisitor('onDefinePropsExit', node, definePropsMap.get(node))
1135+
definePropsMap.delete(node)
1136+
}
11361137
}
11371138
}
11381139

Diff for: tests/lib/rules/require-prop-type-constructor.js

+30
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,36 @@ ruleTester.run('require-prop-type-constructor', rule, {
355355
line: 18
356356
}
357357
]
358+
},
359+
{
360+
filename: 'SomeComponent.vue',
361+
code: `
362+
<script setup>
363+
defineProps({
364+
a: {
365+
type: 'String',
366+
default: 'abc'
367+
},
368+
})
369+
</script>
370+
`,
371+
output: `
372+
<script setup>
373+
defineProps({
374+
a: {
375+
type: String,
376+
default: 'abc'
377+
},
378+
})
379+
</script>
380+
`,
381+
parser: require.resolve('vue-eslint-parser'),
382+
errors: [
383+
{
384+
message: 'The "a" property should be a constructor.',
385+
line: 5
386+
}
387+
]
358388
}
359389
]
360390
})

0 commit comments

Comments
 (0)