Skip to content

useVueConsistentDefineEmitsDeclaration (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueConsistentDefineEmitsDeclaration": "error"
}
}
}
}

Enforce a consistent declaration style for Vue’s defineEmits macro.

In <script setup lang="ts">, Vue lets you declare the events a component emits in two ways: with a TypeScript type passed between angle brackets, or with an argument, such as a list of event names. A type lets TypeScript check the name and the arguments of every event that the component emits. This rule enforces one style throughout the project.

Only <script setup lang="ts"> blocks are checked, because the type style requires TypeScript.

<script setup lang="ts">
const emit = defineEmits(["change", "update"]);
</script>
code-block.vue:2:14 lint/nursery/useVueConsistentDefineEmitsDeclaration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This defineEmits call declares events with an argument instead of a type.

1 │ <script setup lang="ts">
> 2 │ const emit = defineEmits(["change", "update"]);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ A type lets TypeScript check the name and the arguments of every event that the component emits.

ℹ Pass the events as a type between angle brackets, for example defineEmits<{ change: [id: number] }>().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup lang="ts">
const emit = defineEmits({
change: (id) => typeof id === "number",
});
</script>
code-block.vue:2:14 lint/nursery/useVueConsistentDefineEmitsDeclaration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This defineEmits call declares events with an argument instead of a type.

1 │ <script setup lang="ts">
> 2 │ const emit = defineEmits({
│ ^^^^^^^^^^^^^
> 3 │ change: (id) => typeof id === "number",
> 4 │ });
│ ^^
5 │ </script>
6 │

ℹ A type lets TypeScript check the name and the arguments of every event that the component emits.

ℹ Pass the events as a type between angle brackets, for example defineEmits<{ change: [id: number] }>().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup lang="ts">
defineEmits<{
(e: "change", id: number): void;
(e: "update", value: string): void;
}>();
defineEmits<{
change: [id: number];
update: [value: string];
}>();
</script>

Default: "type"

The style that defineEmits calls must use:

  • "type": declare events with a type.
  • "typeLiteral": declare events with a type in which each property is an event name, and the type of the property lists the arguments of the event, such as { change: [id: number] }. This style is shorter than function signatures such as (e: "change", id: number): void, and requires Vue 3.3 or later.
  • "runtime": declare events with an argument, such as defineEmits(["change"]).
biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueConsistentDefineEmitsDeclaration": {
"level": "on",
"options": {
"style": "typeLiteral"
}
}
}
}
}
}
<script setup lang="ts">
const emit = defineEmits<{
(e: "change", id: number): void;
}>();
</script>
code-block.vue:3:3 lint/nursery/useVueConsistentDefineEmitsDeclaration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This declares events with a function signature instead of a property.

1 │ <script setup lang="ts">
2 │ const emit = defineEmits<{
> 3 │ (e: "change", id: number): void;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 │ }>();
5 │ </script>

ℹ Declaring each event as a property is shorter: the name of the property is the name of the event, and its type lists the arguments of the event.

ℹ Declare the event as a property, for example change: [id: number].

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup lang="ts">
const emit = defineEmits(["change"]);
</script>
code-block.vue:2:14 lint/nursery/useVueConsistentDefineEmitsDeclaration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This defineEmits call declares events with an argument instead of a type.

1 │ <script setup lang="ts">
> 2 │ const emit = defineEmits(["change"]);
│ ^^^^^^^^^^^^^^^^^^^^^^^
3 │ </script>
4 │

ℹ A type lets TypeScript check the name and the arguments of every event that the component emits.

ℹ Pass the events as a type between angle brackets, for example defineEmits<{ change: [id: number] }>().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup lang="ts">
const emit = defineEmits<{
change: [id: number];
}>();
</script>
biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueConsistentDefineEmitsDeclaration": {
"level": "on",
"options": {
"style": "runtime"
}
}
}
}
}
}
<script setup lang="ts">
const emit = defineEmits<{
change: [id: number];
}>();
</script>
code-block.vue:2:14 lint/nursery/useVueConsistentDefineEmitsDeclaration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This defineEmits call declares events with a type instead of an argument.

1 │ <script setup lang="ts">
> 2 │ const emit = defineEmits<{
│ ^^^^^^^^^^^^^
> 3 │ change: [id: number];
> 4 │ }>();
│ ^^^^
5 │ </script>
6 │

ℹ This project declares events with an argument, so that every component declares its events the same way.

ℹ Pass the events as an argument, for example defineEmits(['change']).

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

<script setup lang="ts">
defineEmits(["change", "update"]);
defineEmits({
change: (id) => typeof id === "number",
});
</script>