typescriptvue.jsvuejs3

How to define Vue's 3 emit


I'm looking for if it is possible to define the type of the emits. In a SFC in a script setup we can do (docs):

<script setup lang="ts">
// runtime
const emit = defineEmits(['change', 'update'])

// type-based
const emit = defineEmits<{
  (e: 'change', id: number): void
  (e: 'update', value: string): void
}>()
</script>

Since I'm looking for is a way to define the same thing but in a render function based:

export const ComponentA = defineComponent({
  props: {...},
  setup() {
    const emit = defineEmits<{
      (e: 'change', id: number): void
      (e: 'update', value: string): void
    }>()
  }
})

unfortunately I get the following error defineEmits() is a compiler-hint helper that is only usable inside <script setup> of a single file component..

Is there a way to define the events being fired and their types?


Solution

  • You can't declare emits from within setup(), but you can use the emits option alongside the setup() hook, and access the emits from the context argument's emit property (i.e., via the 2nd argument of setup()):

    import { defineComponent } from 'vue'
    
    export const ComponentA = defineComponent({
        👇
      emits: {
        change: (id: number) => true,
        update: (value: string) => true,
      },
      setup(props, { emit }) {
        // @ts-expect-error
        emit('change', 'foo')
        // @ts-expect-error
        emit('update', 100)
        // ok
        emit('change', 100)
        // ok
        emit('update', 'x')
      }
    })
    

    demo