Enforce defineComponent for options API components with Typescript
Please describe what the rule should do:
When we use Option API (in typescript and javascript) it is better to use defineComponent to enable props type inference (1). A rule should be available to enforce it.
What category should the rule belong to?
- [ ] Enforces code style (layout)
- [x] Warns about a potential error (problem)
- [ ] Suggests an alternate way of doing something (suggestion)
- [ ] Other (please specify:)
Provide 2-3 code examples that this rule should warn about:
Should error on:
<script lang="ts">
export default {
// ...
}
</script>
<script>
export default {
// ...
}
</script>
Should not error on:
<script lang="ts">
export default defineComponent({
// ...
})
</script>
<script setup>
// ...
</script>
<script lang="ts" setup>
// ...
</script>
Additional context
(1) source : https://vuejs.org/guide/typescript/composition-api#without-script-setup
Thanks for the suggestion! I think it would be a good rule, but not only for lang="ts", but all Vue components (that are defined using the Options API, not for <script setup>). This is because even for JavaScript components, using defineComponent helps autocompletion in the editor, prepares for a possible TypeScript migration, and increases consistency, with no downsides.
So it should also report an error for:
<script>
export default {
// ...
}
</script>
And for Vue 2's way of getting TypeScript support:
<script>
export default Vue.extend({
// ...
})
</script>
As a name, I'd suggest vue/prefer-define-component. In v10, I think this could be added to the recommended configs. PRs to implement this are welcome :slightly_smiling_face:
The implementation might be somewhat similar to vue/require-direct-export, vue/require-default-export and vue/one-component-per-file.
In Vue 2.7 the defineComponent() function was backported from Vue 3, while it isn't perfect (props and methods don't get auto-completed because of bugs in Vue 2's types that will never get fixed as Vue 2 is EOL), at least in my experience it provides better auto-complete than Vue.extend(). It also has the advantage of also existing in Vue 3, so people who want to migrate to Vue 3 have to change less code when they use defineComponent() than they would have to with Vue.extend().