diff --git a/lib/rules/define-props-declaration.js b/lib/rules/define-props-declaration.js index 39494bd94..47d927dde 100644 --- a/lib/rules/define-props-declaration.js +++ b/lib/rules/define-props-declaration.js @@ -14,8 +14,7 @@ const mapNativeType = (/** @type {string} */ nativeType) => { case 'Number': { return 'number' } - case 'Boolean': - case 'BigInt': { + case 'Boolean': { return 'boolean' } case 'Object': { @@ -41,26 +40,19 @@ const mapNativeType = (/** @type {string} */ nativeType) => { * @param {SourceCode} sourceCode */ function getComponentPropData(prop, sourceCode) { - const unknownType = { - name: prop.propName, - type: 'unknown', - required: undefined, - defaultValue: undefined - } - if (prop.type !== 'object') { - return unknownType + throw new Error(`Unexpected prop type: ${prop.type}.`) } const type = optionGetType(prop.value, sourceCode) if (type === null) { - return unknownType + throw new Error(`Unexpected prop type: ${prop.type}.`) } const required = optionGetRequired(prop.value) const defaultValue = optionGetDefault(prop.value) return { name: prop.propName, - type: mapNativeType(type), + type, required, defaultValue } @@ -74,7 +66,7 @@ function getComponentPropData(prop, sourceCode) { function optionGetType(node, sourceCode) { switch (node.type) { case 'Identifier': { - return node.name + return mapNativeType(node.name) } case 'ObjectExpression': { // foo: { @@ -107,7 +99,17 @@ function optionGetType(node, sourceCode) { return optionGetType(typeProperty.value, sourceCode) } case 'ArrayExpression': { - return null + return node.elements + .map((element) => { + // TODO handle SpreadElement + if (element === null || element.type === 'SpreadElement') { + return null + } + + return optionGetType(element, sourceCode) + }) + .filter(Boolean) + .join(' | ') } case 'FunctionExpression': case 'ArrowFunctionExpression': { @@ -217,7 +219,9 @@ module.exports = { const definePropsType = `{ ${propTypes .map( ({ name, type, required, defaultValue }) => - `${name}${required === false || defaultValue ? '?' : ''}: ${type}` + `${name}${ + required === false || defaultValue ? '?' : '' + }: ${type}` ) .join(', ')} }` @@ -227,7 +231,9 @@ module.exports = { // add type annotation if (separateInterface) { const variableDeclarationNode = node.parent.parent - if (!variableDeclarationNode) return + if (!variableDeclarationNode) { + return + } yield fixer.insertTextBefore( variableDeclarationNode, diff --git a/tests/lib/rules/define-props-declaration.js b/tests/lib/rules/define-props-declaration.js index dd98c3a2f..caf822193 100644 --- a/tests/lib/rules/define-props-declaration.js +++ b/tests/lib/rules/define-props-declaration.js @@ -564,6 +564,31 @@ tester.run('define-props-declaration', rule, { } ] }, + // Array of types + { + only: true, + filename: 'test.vue', + code: ` + + `, + output: ` + + `, + errors: [ + { + message: 'Use type-based declaration instead of runtime declaration.', + line: 3 + } + ] + }, // runtime { filename: 'test.vue',