diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap
index b876743fe..16566fdbc 100644
--- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineEmits.spec.ts.snap
@@ -16,13 +16,15 @@ return { myEmit }
exports[`defineEmits > w/ enum value 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
-enum Foo { BAR = 'bar' }
+enum Foo { BAR = 'bar', BAZ = 'baz', QUX = 'qux' }
+ type BAZ = Foo.BAZ
interface Emits {
(e: Foo.BAR, value: string): void;
+ (e: BAZ, value: string): void;
}
export default /*#__PURE__*/_defineComponent({
- emits: [\\"bar\\"],
+ emits: [\\"bar\\", \\"baz\\"],
setup(__props, { expose: __expose, emit }) {
__expose();
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineEmits.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineEmits.spec.ts
index d7e0fff63..81dbba941 100644
--- a/packages/compiler-sfc/__tests__/compileScript/defineEmits.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript/defineEmits.spec.ts
@@ -92,15 +92,17 @@ const emit = defineEmits(['a', 'b'])
test('w/ enum value', () => {
const { content } = compile(`
`)
assertCode(content)
- expect(content).toMatch(`emits: ["bar"]`)
+ expect(content).toMatch(`emits: ["bar", "baz"]`)
})
test('w/ type from normal script', () => {
diff --git a/packages/compiler-sfc/src/script/defineEmits.ts b/packages/compiler-sfc/src/script/defineEmits.ts
index 719b1db5d..aca8c7c68 100644
--- a/packages/compiler-sfc/src/script/defineEmits.ts
+++ b/packages/compiler-sfc/src/script/defineEmits.ts
@@ -1,7 +1,17 @@
-import { Identifier, LVal, Node, RestElement } from '@babel/types'
+import {
+ Identifier,
+ LVal,
+ Node,
+ RestElement,
+ TSEnumDeclaration
+} from '@babel/types'
import { isCallOf } from './utils'
import { ScriptCompileContext } from './context'
-import { resolveTypeElements, resolveUnionType } from './resolveType'
+import {
+ resolveTypeElements,
+ resolveUnionType,
+ resolveTypeReference
+} from './resolveType'
export const DEFINE_EMITS = 'defineEmits'
@@ -102,7 +112,8 @@ function extractEventNames(
eventName.typeAnnotation &&
eventName.typeAnnotation.type === 'TSTypeAnnotation'
) {
- const types = resolveUnionType(ctx, eventName.typeAnnotation.typeAnnotation)
+ const typeNode = eventName.typeAnnotation.typeAnnotation
+ const types = resolveUnionType(ctx, typeNode)
for (const type of types) {
if (type.type === 'TSLiteralType') {
@@ -113,12 +124,43 @@ function extractEventNames(
emits.add(String(type.literal.value))
}
} else if (type.type === 'TSEnumDeclaration') {
- for (const m of type.members) {
- if (m.initializer && m.initializer.type === 'StringLiteral') {
- emits.add(String(m.initializer.value))
+ if (typeNode.type === 'TSTypeReference') {
+ if (typeNode.typeName.type === 'TSQualifiedName') {
+ extractEnumValue(type, typeNode.typeName.right.name, emits)
+ }
+ }
+ } else if (type.type === 'TSTypeReference') {
+ if (
+ type.typeName.type === 'TSQualifiedName' &&
+ type.typeName.left.type === 'Identifier'
+ ) {
+ const resolved = resolveTypeReference(
+ ctx,
+ type,
+ undefined,
+ type.typeName.left.name
+ )
+ if (resolved && resolved.type === 'TSEnumDeclaration') {
+ extractEnumValue(resolved, type.typeName.right.name, emits)
}
}
}
}
}
}
+function extractEnumValue(
+ typeNode: TSEnumDeclaration,
+ typeName: string,
+ emits: Set
+) {
+ for (const m of typeNode.members) {
+ if (
+ m.id.type === 'Identifier' &&
+ m.id.name === typeName &&
+ m.initializer &&
+ m.initializer.type === 'StringLiteral'
+ ) {
+ emits.add(String(m.initializer.value))
+ }
+ }
+}
diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts
index 8d67ab968..afce63c6a 100644
--- a/packages/compiler-sfc/src/script/resolveType.ts
+++ b/packages/compiler-sfc/src/script/resolveType.ts
@@ -593,7 +593,7 @@ type ReferenceTypes =
| TSImportType
| TSTypeQuery
-function resolveTypeReference(
+export function resolveTypeReference(
ctx: TypeResolveContext,
node: ReferenceTypes & {
_resolvedReference?: ScopeTypeNode