fix(compiler-sfc): support resolve enum value for defineEmits

This commit is contained in:
edison1105 2023-06-01 20:57:18 +08:00
parent a95e612b25
commit d39ad4fe37
4 changed files with 69 additions and 15 deletions

View File

@ -30,6 +30,26 @@ return { emit }
})" })"
`; `;
exports[`defineEmits > w/ type (enum) 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
enum Foo { BAR = 'bar' }
interface Emits {
(e: Foo.BAR, value: string): void;
}
export default /*#__PURE__*/_defineComponent({
emits: [\\"bar\\"],
setup(__props, { expose: __expose, emit }) {
__expose();
return { Foo, emit }
}
})"
`;
exports[`defineEmits > w/ type (exported interface) 1`] = ` exports[`defineEmits > w/ type (exported interface) 1`] = `
"import { defineComponent as _defineComponent } from 'vue' "import { defineComponent as _defineComponent } from 'vue'
export interface Emits { (e: 'foo' | 'bar'): void } export interface Emits { (e: 'foo' | 'bar'): void }

View File

@ -89,6 +89,20 @@ const emit = defineEmits(['a', 'b'])
expect(content).toMatch(`emits: ["foo", "bar"]`) expect(content).toMatch(`emits: ["foo", "bar"]`)
}) })
test('w/ enum value', () => {
const { content } = compile(`
<script setup lang="ts">
enum Foo { BAR = 'bar' }
interface Emits {
(e: Foo.BAR, value: string): void;
}
const emit = defineEmits<Emits>()
</script>
`)
assertCode(content)
expect(content).toMatch(`emits: ["bar"]`)
})
test('w/ type from normal script', () => { test('w/ type from normal script', () => {
const { content } = compile(` const { content } = compile(`
<script lang="ts"> <script lang="ts">

View File

@ -112,6 +112,12 @@ function extractEventNames(
) { ) {
emits.add(String(type.literal.value)) 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))
}
}
} }
} }
} }

View File

@ -650,24 +650,38 @@ function innerResolveTypeReference(
} }
} }
} else { } else {
let ns = innerResolveTypeReference(ctx, scope, name[0], node, onlyExported) let resolved = innerResolveTypeReference(
if (ns) { ctx,
if (ns.type !== 'TSModuleDeclaration') { scope,
name[0],
node,
onlyExported
)
if (resolved) {
if (resolved.type === 'TSEnumDeclaration') {
return resolved
} else {
if (resolved.type !== 'TSModuleDeclaration') {
// namespace merged with other types, attached as _ns // namespace merged with other types, attached as _ns
ns = ns._ns resolved = resolved._ns
} }
if (ns) { if (resolved) {
const childScope = moduleDeclToScope(ctx, ns, ns._ownerScope || scope) const childScope = moduleDeclToScope(
ctx,
resolved,
resolved._ownerScope || scope
)
return innerResolveTypeReference( return innerResolveTypeReference(
ctx, ctx,
childScope, childScope,
name.length > 2 ? name.slice(1) : name[name.length - 1], name.length > 2 ? name.slice(1) : name[name.length - 1],
node, node,
!ns.declare !resolved.declare
) )
} }
} }
} }
}
} }
function getReferenceName(node: ReferenceTypes): string | string[] { function getReferenceName(node: ReferenceTypes): string | string[] {