Subscribe on changes!

SFC compiler goes into infinite loop on bad defineEmit

avatar
Jan 8th 2021

Version

3.0.5

Reproduction link

https://github.com/vitejs/vite/issues/1436

Steps to reproduce

See link for original context.

Try to compile a bad defineEmit

// This is not correct usage
defineEmit<{ myEvent(id: number): void }>();

What is expected?

Some kind of error message?

What is actually happening?

SFC compiler goes into an infinite loop


The typing of T in defineEmit<T> does not extend Function or anything, so there's no IDE feedback on improper usage such as this example. Would be nice to harden the typing here, if possible.

avatar
Jan 10th 2021

The compileScript has already thrown an error for this:

3041610255734_ pic_hd

avatar
Jan 10th 2021

I tried to create a minimal repro and indeed, I observed the same error as @HcySunYang. I guess I'll have to find out why in my real project it goes into an infinite loop. Just commenting out the bad defineEmit fixes it but there must be something else required to trigger the bug. I'll post here if I find out what is the exact condition for the bug to occur.

In the meantime, I noticed that the type validation isn't perfect. This doesn't produce the expected error (doesn't go into a loop either):

defineEmit<((c: number) => void) | { a(n: number): void }>()
avatar
Jan 11th 2021

I think the TSMethodSignature syntax({ a(n: number): void }) can be supported like https://github.com/vuejs/vue-next/pull/2984

avatar
Jan 11th 2021

Closing in favor of https://github.com/vuejs/vue-next/issues/2983 since this one has no reproduction

avatar
Jan 11th 2021

@posva This issue here is about defineEmit, while #2983 is about defineProps, I think we should reopen this one again.

avatar
Jan 11th 2021

Yes, those are 2 different issues. I'll reopen this one if I manage to create a minimal repro.

avatar
Jan 11th 2021

You are right, I missed the names! A new issue with a proper repro like the other one is still preferred, thanks!

avatar
Jan 11th 2021

Quick heads-up: I can confirm my real project still goes in an infinite loop in Vite when I change the correct definEmit for this bad guy:

const emits = defineEmit<{ showRevision(e: 'showRevision', sha: string): void }>();

As that doesn't seem to be sufficient I'll try to work out a repro if I have the time to do so. But as this isn't blocking (code was invalid after all), it's a bit low-priority for me.