diff --git a/lib/rules/require-prop-type-constructor.js b/lib/rules/require-prop-type-constructor.js index 0f94f0f2c..f22da8118 100644 --- a/lib/rules/require-prop-type-constructor.js +++ b/lib/rules/require-prop-type-constructor.js @@ -7,6 +7,12 @@ const utils = require('../utils') const { isDef } = require('../utils') +/** + * @typedef {import('../utils').ComponentArrayProp} ComponentArrayProp + * @typedef {import('../utils').ComponentObjectProp} ComponentObjectProp + * @typedef {import('../utils').ComponentTypeProp} ComponentTypeProp + */ + // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ @@ -76,8 +82,9 @@ module.exports = { ) } - return utils.executeOnVueComponent(context, (obj) => { - for (const prop of utils.getComponentProps(obj)) { + /** @param {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} props */ + function verifyProps(props) { + for (const prop of props) { if (!prop.value || prop.propName == null) { continue } @@ -94,6 +101,17 @@ module.exports = { checkPropertyNode(prop.propName, typeProperty.value) } } - }) + } + + return utils.compositingVisitors( + utils.defineScriptSetupVisitor(context, { + onDefinePropsEnter(_node, props) { + verifyProps(props) + } + }), + utils.executeOnVueComponent(context, (obj) => { + verifyProps(utils.getComponentProps(obj)) + }) + ) } } diff --git a/lib/utils/index.js b/lib/utils/index.js index 5ecda2868..484074035 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -1097,42 +1097,43 @@ module.exports = { return null } - const definePropsMap = new Map() - /** - * @param {CallExpression} node - */ - scriptSetupVisitor.CallExpression = (node) => { - if ( - inScriptSetup(node) && - node.callee.type === 'Identifier' && - node.callee.name === 'defineProps' - ) { - /** @type {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} */ - let props = [] - if (node.arguments.length >= 1) { - const defNode = getObjectOrArray(node.arguments[0]) - if (defNode) { - props = getComponentPropsFromDefine(defNode) - } - } else if ( - node.typeParameters && - node.typeParameters.params.length >= 1 + if (visitor.onDefinePropsEnter || visitor.onDefinePropsExit) { + const definePropsMap = new Map() + /** + * @param {CallExpression} node + */ + scriptSetupVisitor.CallExpression = (node) => { + if ( + inScriptSetup(node) && + node.callee.type === 'Identifier' && + node.callee.name === 'defineProps' ) { - props = getComponentPropsFromTypeDefine( - context, - node.typeParameters.params[0] - ) + /** @type {(ComponentArrayProp | ComponentObjectProp | ComponentTypeProp)[]} */ + let props = [] + if (node.arguments.length >= 1) { + const defNode = getObjectOrArray(node.arguments[0]) + if (defNode) { + props = getComponentPropsFromDefine(defNode) + } + } else if ( + node.typeParameters && + node.typeParameters.params.length >= 1 + ) { + props = getComponentPropsFromTypeDefine( + context, + node.typeParameters.params[0] + ) + } + callVisitor('onDefinePropsEnter', node, props) } - definePropsMap.set(node, props) - callVisitor('onDefinePropsEnter', node, props) + callVisitor('CallExpression', node) } - callVisitor('CallExpression', node) - } - scriptSetupVisitor['CallExpression:exit'] = (node) => { - callVisitor('CallExpression:exit', node) - if (definePropsMap.has(node)) { - callVisitor('onDefinePropsExit', node, definePropsMap.get(node)) - definePropsMap.delete(node) + scriptSetupVisitor['CallExpression:exit'] = (node) => { + callVisitor('CallExpression:exit', node) + if (definePropsMap.has(node)) { + callVisitor('onDefinePropsExit', node, definePropsMap.get(node)) + definePropsMap.delete(node) + } } } diff --git a/tests/lib/rules/require-prop-type-constructor.js b/tests/lib/rules/require-prop-type-constructor.js index 18ece4f55..452bb35aa 100644 --- a/tests/lib/rules/require-prop-type-constructor.js +++ b/tests/lib/rules/require-prop-type-constructor.js @@ -355,6 +355,36 @@ ruleTester.run('require-prop-type-constructor', rule, { line: 18 } ] + }, + { + filename: 'SomeComponent.vue', + code: ` + + `, + output: ` + + `, + parser: require.resolve('vue-eslint-parser'), + errors: [ + { + message: 'The "a" property should be a constructor.', + line: 5 + } + ] } ] })