Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
peter50216 opened this issue Dec 24, 2020 · 2 comments
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope: types

Comments

@peter50216
Copy link

peter50216 commented Dec 24, 2020

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;}.

@peter50216
Copy link
Author

((e: 'foo' | 'bar') => void) & ((e: 'baz', id: number) => void) also works for TypeScript, but vue compiler reject this too.

@Blackfaded
Copy link

With an interface I also gen a compiler Error:

interface Emit {
  (e: 'delete', id: string): void;
  (e: 'duplicate', id: string): void;
  (e: 'start', id: string): void;
}
const emit = defineEmit<Emit>();
Syntax Error: TypeError: Cannot read property 'content' of null

Bildschirmfoto 2021-03-12 um 09 00 31

But the types ware correct. Any solutions to this? :)

@HcySunYang HcySunYang added the 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. label Mar 29, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Oct 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope: types
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants