diff --git a/packages/compiler-sfc/src/script/defineEmits.ts b/packages/compiler-sfc/src/script/defineEmits.ts index e615cd71a0d..a50cf91fc4a 100644 --- a/packages/compiler-sfc/src/script/defineEmits.ts +++ b/packages/compiler-sfc/src/script/defineEmits.ts @@ -1,7 +1,7 @@ import { Identifier, LVal, Node, RestElement } from '@babel/types' import { isCallOf } from './utils' import { ScriptCompileContext } from './context' -import { resolveTypeElements } from './resolveType' +import { resolveTypeElements, resolveUnionType } from './resolveType' export const DEFINE_EMITS = 'defineEmits' @@ -65,7 +65,7 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set { const node = ctx.emitsTypeDecl! if (node.type === 'TSFunctionType') { - extractEventNames(node.parameters[0], emits) + extractEventNames(ctx, node.parameters[0], emits) return emits } @@ -85,7 +85,7 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set { ) } for (const call of calls) { - extractEventNames(call.parameters[0], emits) + extractEventNames(ctx, call.parameters[0], emits) } } @@ -93,6 +93,7 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set { } function extractEventNames( + ctx: ScriptCompileContext, eventName: Identifier | RestElement, emits: Set ) { @@ -101,22 +102,15 @@ function extractEventNames( eventName.typeAnnotation && eventName.typeAnnotation.type === 'TSTypeAnnotation' ) { - const typeNode = eventName.typeAnnotation.typeAnnotation - if (typeNode.type === 'TSLiteralType') { - if ( - typeNode.literal.type !== 'UnaryExpression' && - typeNode.literal.type !== 'TemplateLiteral' - ) { - emits.add(String(typeNode.literal.value)) - } - } else if (typeNode.type === 'TSUnionType') { - for (const t of typeNode.types) { + const types = resolveUnionType(ctx, eventName.typeAnnotation.typeAnnotation) + + for (const type of types) { + if (type.type === 'TSLiteralType') { if ( - t.type === 'TSLiteralType' && - t.literal.type !== 'UnaryExpression' && - t.literal.type !== 'TemplateLiteral' + type.literal.type !== 'UnaryExpression' && + type.literal.type !== 'TemplateLiteral' ) { - emits.add(String(t.literal.value)) + emits.add(String(type.literal.value)) } } } diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts index e79d21f8419..007d8e2ddf1 100644 --- a/packages/compiler-sfc/src/script/resolveType.ts +++ b/packages/compiler-sfc/src/script/resolveType.ts @@ -588,7 +588,7 @@ type ReferenceTypes = | TSImportType | TSTypeQuery -function resolveTypeReference( +export function resolveTypeReference( ctx: TypeResolveContext, node: ReferenceTypes & { _resolvedReference?: ScopeTypeNode @@ -1605,3 +1605,23 @@ function resolveReturnType( return resolved.returnType } } + +export function resolveUnionType( + ctx: TypeResolveContext, + node: Node & MaybeWithScope & { _resolvedElements?: ResolvedElements }, + scope?: TypeScope +): Node[] { + if (node.type === 'TSTypeReference') { + const resolved = resolveTypeReference(ctx, node, scope) + if (resolved) node = resolved + } + + let types: Node[] + if (node.type === 'TSUnionType') { + types = node.types.flatMap(node => resolveUnionType(ctx, node, scope)) + } else { + types = [node] + } + + return types +}