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`] = `
"import { defineComponent as _defineComponent } from 'vue'
export interface Emits { (e: 'foo' | 'bar'): void }

View File

@ -89,6 +89,20 @@ const emit = defineEmits(['a', 'b'])
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', () => {
const { content } = compile(`
<script lang="ts">

View File

@ -112,6 +112,12 @@ 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))
}
}
}
}
}

View File

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