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