Skip to content

script setup: expected TypeScript type by compiler for defineEmit is not useful #2874

@peter50216

Description

@peter50216

Version

3.0.4

Reproduction link

TypeScript Playground

Steps to reproduce

const emit = defineEmit<SOME_TYPE_HERE>();
emit('foo');
emit('bar');
emit('baz', 1);

What is expected?

Should be able to specify SOME_TYPE_HERE correctly so the resulting program has no TypeScript error and no error from vue compiler.

What is actually happening?

  • SOME_TYPE_HERE = ((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void) => TypeScript error
  • SOME_TYPE_HERE = {(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;} => vue compiler error
[@vue/compiler-sfc] type argument passed to defineEmit() must be a function type or a union of function types.

https://github.com/vuejs/vue-next/blob/085bbd5fe07c52056e9f7151fbaed8f6a2e442b3/packages/compiler-sfc/__tests__/compileScript.spec.ts#L522

Currently the type expected for defineEmit is a function type or union type, but the type ((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void) is actually not useful as a emit function, as can be seen in the above TypeScript playground, since the type ((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void) is equivalent to ((e: never, id: number) => void).

The correct way to specifies this seems to be using call signature {(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minor-bugPriority 3: this fixes a bug, but is an edge case that only affects very specific usage.scope: types

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions