Skip to content

Commit

Permalink
fix(compiler-sfc): support type references in unions
Browse files Browse the repository at this point in the history
closes #7943
  • Loading branch information
sxzz committed May 12, 2023
1 parent a374d7e commit 3711523
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 18 deletions.
28 changes: 11 additions & 17 deletions 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'

Expand Down Expand Up @@ -65,7 +65,7 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
const node = ctx.emitsTypeDecl!

if (node.type === 'TSFunctionType') {
extractEventNames(node.parameters[0], emits)
extractEventNames(ctx, node.parameters[0], emits)
return emits
}

Expand All @@ -85,14 +85,15 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
)
}
for (const call of calls) {
extractEventNames(call.parameters[0], emits)
extractEventNames(ctx, call.parameters[0], emits)
}
}

return emits
}

function extractEventNames(
ctx: ScriptCompileContext,
eventName: Identifier | RestElement,
emits: Set<string>
) {
Expand All @@ -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))
}
}
}
Expand Down
22 changes: 21 additions & 1 deletion packages/compiler-sfc/src/script/resolveType.ts
Expand Up @@ -588,7 +588,7 @@ type ReferenceTypes =
| TSImportType
| TSTypeQuery

function resolveTypeReference(
export function resolveTypeReference(
ctx: TypeResolveContext,
node: ReferenceTypes & {
_resolvedReference?: ScopeTypeNode
Expand Down Expand Up @@ -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
}

0 comments on commit 3711523

Please sign in to comment.