Skip to content

Commit 1d58a2b

Browse files
committed
feature: handle array as props list (vuejs#2465)
1 parent 0bd915b commit 1d58a2b

File tree

2 files changed

+54
-20
lines changed

2 files changed

+54
-20
lines changed

lib/rules/define-props-declaration.js

+30-16
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ function* fixTypeBased(fixer, node, props, context) {
3232
}
3333
)
3434

35-
const componentPropsTypeCode = `{ ${componentPropsTypes.join(PROPS_SEPARATOR)} }`
35+
const componentPropsTypeCode = `{ ${componentPropsTypes.join(
36+
PROPS_SEPARATOR
37+
)} }`
3638

3739
// remove defineProps function parameters
3840
yield fixer.replaceText(node.arguments[0], '')
@@ -96,22 +98,34 @@ const mapNativeType = (nativeType) => {
9698
* @param {SourceCode} sourceCode
9799
*/
98100
function getComponentPropData(prop, sourceCode) {
99-
if (prop.propName === null) {
100-
throw new Error('Unexpected prop with null name.')
101-
}
102-
if (prop.type !== 'object') {
103-
throw new Error(`Unexpected prop type: ${prop.type}.`)
104-
}
105-
const type = optionGetType(prop.value, sourceCode)
106-
const required = optionGetRequired(prop.value)
107-
const defaultValue = optionGetDefault(prop.value)
108-
109-
return {
110-
name: prop.propName,
111-
type,
112-
required,
113-
defaultValue
101+
if (prop.type === 'array') {
102+
if (prop.node.type !== 'Identifier') {
103+
throw new Error(`Unexpected prop type inside array: ${prop.node.type}`)
104+
}
105+
106+
return {
107+
name: prop.node.name,
108+
type: 'string',
109+
required: false,
110+
defaultValue: undefined
111+
}
112+
} else if (prop.type === 'object') {
113+
if (prop.propName === null) {
114+
throw new Error('Unexpected prop with null name.')
115+
}
116+
117+
const type = optionGetType(prop.value, sourceCode)
118+
const required = optionGetRequired(prop.value)
119+
const defaultValue = optionGetDefault(prop.value)
120+
121+
return {
122+
name: prop.propName,
123+
type,
124+
required,
125+
defaultValue
126+
}
114127
}
128+
throw new Error(`Unexpected prop type: ${prop.type}.`)
115129
}
116130

117131
/**

tests/lib/rules/define-props-declaration.js

+24-4
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ tester.run('define-props-declaration', rule, {
365365
code: `
366366
<script setup lang="ts">
367367
interface Kind { id: number; name: string }
368-
368+
369369
const props = defineProps({
370370
kind: {
371371
type: Object as PropType<Kind>,
@@ -376,7 +376,7 @@ tester.run('define-props-declaration', rule, {
376376
output: `
377377
<script setup lang="ts">
378378
interface Kind { id: number; name: string }
379-
379+
380380
const props = defineProps<{ kind?: Kind }>()
381381
</script>
382382
`,
@@ -393,7 +393,7 @@ tester.run('define-props-declaration', rule, {
393393
code: `
394394
<script setup lang="ts">
395395
import Kind from 'test'
396-
396+
397397
const props = defineProps({
398398
kind: {
399399
type: Object as PropType<Kind>,
@@ -404,7 +404,7 @@ tester.run('define-props-declaration', rule, {
404404
output: `
405405
<script setup lang="ts">
406406
import Kind from 'test'
407-
407+
408408
const props = defineProps<{ kind?: Kind }>()
409409
</script>
410410
`,
@@ -633,6 +633,26 @@ tester.run('define-props-declaration', rule, {
633633
line: 3
634634
}
635635
]
636+
},
637+
// array
638+
{
639+
filename: 'test.vue',
640+
code: `
641+
<script setup lang="ts">
642+
const props = defineProps([kind])
643+
</script>
644+
`,
645+
output: `
646+
<script setup lang="ts">
647+
const props = defineProps<{ kind?: string }>()
648+
</script>
649+
`,
650+
errors: [
651+
{
652+
message: 'Use type-based declaration instead of runtime declaration.',
653+
line: 3
654+
}
655+
]
636656
}
637657
]
638658
})

0 commit comments

Comments
 (0)