eslint-plugin-vue icon indicating copy to clipboard operation
eslint-plugin-vue copied to clipboard

Enforce defineComponent for options API components with Typescript

Open GeoffreyParrier opened this issue 11 months ago • 2 comments

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

GeoffreyParrier avatar Dec 27 '24 13:12 GeoffreyParrier

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.

FloEdelmann avatar Jan 02 '25 10:01 FloEdelmann

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().

absidue avatar Jan 05 '25 22:01 absidue