Skip to content

Commit 774056c

Browse files
authored
Update vue/require-prop-type-constructor rule to support <script setup> (#1536)
* Update `vue/require-prop-type-constructor` rule to support `<script setup>` * fix tsc error
1 parent 3262d93 commit 774056c

File tree

3 files changed

+85
-36
lines changed

3 files changed

+85
-36
lines changed

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

+21-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
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+
* @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp
14+
*/
15+
1016
// ------------------------------------------------------------------------------
1117
// Rule Definition
1218
// ------------------------------------------------------------------------------
@@ -76,8 +82,9 @@ module.exports = {
7682
)
7783
}
7884

79-
return utils.executeOnVueComponent(context, (obj) => {
80-
for (const prop of utils.getComponentProps(obj)) {
85+
/** @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props */
86+
function verifyProps(props) {
87+
for (const prop of props) {
8188
if (!prop.value || prop.propName == null) {
8289
continue
8390
}
@@ -94,6 +101,17 @@ module.exports = {
94101
checkPropertyNode(prop.propName, typeProperty.value)
95102
}
96103
}
97-
})
104+
}
105+
106+
return utils.compositingVisitors(
107+
utils.defineScriptSetupVisitor(context, {
108+
onDefinePropsEnter(_node, props) {
109+
verifyProps(props)
110+
}
111+
}),
112+
utils.executeOnVueComponent(context, (obj) => {
113+
verifyProps(utils.getComponentProps(obj))
114+
})
115+
)
98116
}
99117
}

Diff for: lib/utils/index.js

+34-33
Original file line numberDiff line numberDiff line change
@@ -1103,42 +1103,43 @@ module.exports = {
11031103
return null
11041104
}
11051105

1106-
const definePropsMap = new Map()
1107-
/**
1108-
* @param {CallExpression} node
1109-
*/
1110-
scriptSetupVisitor.CallExpression = (node) => {
1111-
if (
1112-
inScriptSetup(node) &&
1113-
node.callee.type === 'Identifier' &&
1114-
node.callee.name === 'defineProps'
1115-
) {
1116-
/** @type {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} */
1117-
let props = []
1118-
if (node.arguments.length >= 1) {
1119-
const defNode = getObjectOrArray(node.arguments[0])
1120-
if (defNode) {
1121-
props = getComponentPropsFromDefine(defNode)
1122-
}
1123-
} else if (
1124-
node.typeParameters &&
1125-
node.typeParameters.params.length >= 1
1106+
if (visitor.onDefinePropsEnter || visitor.onDefinePropsExit) {
1107+
const definePropsMap = new Map()
1108+
/**
1109+
* @param {CallExpression} node
1110+
*/
1111+
scriptSetupVisitor.CallExpression = (node) => {
1112+
if (
1113+
inScriptSetup(node) &&
1114+
node.callee.type === 'Identifier' &&
1115+
node.callee.name === 'defineProps'
11261116
) {
1127-
props = getComponentPropsFromTypeDefine(
1128-
context,
1129-
node.typeParameters.params[0]
1130-
)
1117+
/** @type {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} */
1118+
let props = []
1119+
if (node.arguments.length >= 1) {
1120+
const defNode = getObjectOrArray(node.arguments[0])
1121+
if (defNode) {
1122+
props = getComponentPropsFromDefine(defNode)
1123+
}
1124+
} else if (
1125+
node.typeParameters &&
1126+
node.typeParameters.params.length >= 1
1127+
) {
1128+
props = getComponentPropsFromTypeDefine(
1129+
context,
1130+
node.typeParameters.params[0]
1131+
)
1132+
}
1133+
callVisitor('onDefinePropsEnter', node, props)
11311134
}
1132-
definePropsMap.set(node, props)
1133-
callVisitor('onDefinePropsEnter', node, props)
1135+
callVisitor('CallExpression', node)
11341136
}
1135-
callVisitor('CallExpression', node)
1136-
}
1137-
scriptSetupVisitor['CallExpression:exit'] = (node) => {
1138-
callVisitor('CallExpression:exit', node)
1139-
if (definePropsMap.has(node)) {
1140-
callVisitor('onDefinePropsExit', node, definePropsMap.get(node))
1141-
definePropsMap.delete(node)
1137+
scriptSetupVisitor['CallExpression:exit'] = (node) => {
1138+
callVisitor('CallExpression:exit', node)
1139+
if (definePropsMap.has(node)) {
1140+
callVisitor('onDefinePropsExit', node, definePropsMap.get(node))
1141+
definePropsMap.delete(node)
1142+
}
11421143
}
11431144
}
11441145

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)