Skip to content

Commit

Permalink
feat: autofix in define-props-declaration: runtime syntax to type-b…
Browse files Browse the repository at this point in the history
…ased syntax (vuejs#2465)

handle required option
  • Loading branch information
mpiniarski committed May 27, 2024
1 parent b770232 commit 99e2f3e
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 7 deletions.
37 changes: 30 additions & 7 deletions lib/rules/define-props-declaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,8 @@ module.exports = {
if (typeArgument === undefined) {
return null
}

const text = sourceCode.getText(typeArgument)

return text

return sourceCode.getText(typeArgument)
}
return optionGetType(typeProperty.value)
}
Expand All @@ -113,6 +111,26 @@ module.exports = {
return null
}

/**
* @param {Expression} node
* @returns {boolean | undefined }
*/
function optionGetRequired(node) {
if (node.type === 'ObjectExpression') {
const requiredProperty = utils.findProperty(node, 'required')
if (requiredProperty == null) {
return undefined
}

if (requiredProperty.value.type === 'Literal') {
return Boolean(requiredProperty.value.value)
}
}

// Unknown
return undefined
}

const scriptSetup = utils.getScriptSetupElement(context)
if (!scriptSetup || !utils.hasAttribute(scriptSetup, 'lang', 'ts')) {
return {}
Expand All @@ -129,7 +147,7 @@ module.exports = {
messageId: 'hasArg',
*fix(fixer) {
const propTypes = props.map((prop) => {
const unknownType = { name: prop.propName, type: 'unknown' }
const unknownType = { name: prop.propName, type: 'unknown', required: undefined }

if (prop.type !== 'object') {
return unknownType
Expand All @@ -138,15 +156,20 @@ module.exports = {
if (type === null) {
return unknownType
}
const required = optionGetRequired(prop.value)

return {
name: prop.propName,
type: mapNativeType(type)
type: mapNativeType(type),
required
}
})

const definePropsType = `{ ${propTypes
.map(({ name, type }) => `${name}: ${type}`)
.map(
({ name, type, required }) =>
`${name}${required === false ? '?' : ''}: ${type}`
)
.join(', ')} }`

yield fixer.insertTextAfter(
Expand Down
50 changes: 50 additions & 0 deletions tests/lib/rules/define-props-declaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,56 @@ tester.run('define-props-declaration', rule, {
line: 3
}
]
},
// required
{
filename: 'test.vue',
code: `
<script setup lang="ts">
const props = defineProps({
kind: {
type: String,
required: true
}
})
</script>
`,
output: `
<script setup lang="ts">
const props = defineProps<{ kind: string }>()
</script>
`,
errors: [
{
message: 'Use type-based declaration instead of runtime declaration.',
line: 3
}
]
},
// not required
{
filename: 'test.vue',
code: `
<script setup lang="ts">
const props = defineProps({
kind: {
type: String,
required: false
}
})
</script>
`,
output: `
<script setup lang="ts">
const props = defineProps<{ kind?: string }>()
</script>
`,
errors: [
{
message: 'Use type-based declaration instead of runtime declaration.',
line: 3
}
]
}
]
})

0 comments on commit 99e2f3e

Please sign in to comment.