Skip to content

Commit 5a4a15e

Browse files
committed
feat: autofix in define-props-declaration: runtime syntax to type-based syntax (vuejs#2465)
handle separateInterface rule option
1 parent f0294e8 commit 5a4a15e

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

lib/rules/define-props-declaration.js

+29-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ module.exports = {
5252
schema: [
5353
{
5454
enum: ['type-based', 'runtime']
55+
},
56+
{
57+
type: 'object',
58+
properties: {
59+
separateInterface: {
60+
type: 'boolean',
61+
default: false
62+
}
63+
}
5564
}
5665
],
5766
messages: {
@@ -156,6 +165,8 @@ module.exports = {
156165
}
157166

158167
const defineType = context.options[0] || 'type-based'
168+
const separateInterface = context.options[1]?.separateInterface || false
169+
159170
return utils.defineScriptSetupVisitor(context, {
160171
onDefinePropsEnter(node, props) {
161172
switch (defineType) {
@@ -194,15 +205,28 @@ module.exports = {
194205
const definePropsType = `{ ${propTypes
195206
.map(
196207
({ name, type, required, defaultValue }) =>
197-
`${name}${(required === false || defaultValue) ? '?' : ''}: ${type}`
208+
`${name}${required === false || defaultValue ? '?' : ''}: ${type}`
198209
)
199210
.join(', ')} }`
200211

201212
yield fixer.replaceText(node.arguments[0], '')
202-
yield fixer.insertTextAfter(
203-
node.callee,
204-
`<${definePropsType}>`
205-
)
213+
214+
if (separateInterface) {
215+
const variableDeclarationNode = node.parent.parent
216+
if (!variableDeclarationNode) return
217+
218+
yield fixer.insertTextBefore(
219+
variableDeclarationNode,
220+
`interface Props ${definePropsType.replaceAll(';', ',')}; `
221+
)
222+
yield fixer.insertTextAfter(node.callee, `<Props>`)
223+
} else {
224+
yield fixer.insertTextAfter(
225+
node.callee,
226+
`<${definePropsType}>`
227+
)
228+
}
229+
206230
const defaults = propTypes.filter(
207231
({ defaultValue }) => defaultValue
208232
)

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

+25
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,31 @@ tester.run('define-props-declaration', rule, {
460460
line: 3
461461
}
462462
]
463+
},
464+
// separate interface
465+
{
466+
filename: 'test.vue',
467+
code: `
468+
<script setup lang="ts">
469+
const props = defineProps({
470+
kind: {
471+
type: Object as PropType<{ id: number; name: string }>
472+
}
473+
})
474+
</script>
475+
`,
476+
output: `
477+
<script setup lang="ts">
478+
interface Props { kind: { id: number, name: string } }; const props = defineProps<Props>()
479+
</script>
480+
`,
481+
options: ['type-based', { separateInterface: true }],
482+
errors: [
483+
{
484+
message: 'Use type-based declaration instead of runtime declaration.',
485+
line: 3
486+
}
487+
]
463488
}
464489
]
465490
})

0 commit comments

Comments
 (0)