Skip to content

Enforce defineComponent for options API components with Typescript #2661

Open
@GeoffreyParrier

Description

@GeoffreyParrier

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

Activity

FloEdelmann

FloEdelmann commented on Jan 2, 2025

@FloEdelmann
Member

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 🙂

The implementation might be somewhat similar to vue/require-direct-export, vue/require-default-export and vue/one-component-per-file.

absidue

absidue commented on Jan 5, 2025

@absidue

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

linked a pull request that will close this issue on Apr 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @FloEdelmann@GeoffreyParrier@absidue

      Issue actions

        Enforce defineComponent for options API components with Typescript · Issue #2661 · vuejs/eslint-plugin-vue