feat(compiler-sfc): codegen support for defineEmits() short syntax (followup of #7992)
This commit is contained in:
parent
8876dccf42
commit
ef73ea53ea
|
@ -1478,6 +1478,22 @@ export default /*#__PURE__*/_defineComponent({
|
|||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (tuple syntax) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { expose: __expose, emit }: { emit: ({ foo: [], bar: [] }), expose: any, slots: any, attrs: any }) {
|
||||
__expose();
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
|
|
|
@ -1540,6 +1540,16 @@ const emit = defineEmits(['a', 'b'])
|
|||
expect(content).toMatch(`emits: ['foo']`)
|
||||
})
|
||||
|
||||
test('defineEmits w/ type (tuple syntax)', () => {
|
||||
const { content } = compile(`
|
||||
<script setup lang="ts">
|
||||
const emit = defineEmits<{ foo: [], bar: [] }>()
|
||||
</script>
|
||||
`)
|
||||
expect(content).toMatch(`emits: ["foo", "bar"]`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
test('runtime Enum', () => {
|
||||
const { content, bindings } = compile(
|
||||
`<script setup lang="ts">
|
||||
|
@ -1871,6 +1881,19 @@ const emit = defineEmits(['a', 'b'])
|
|||
</script>`).content
|
||||
)
|
||||
})
|
||||
|
||||
test('mixed usage of tuple / call signature in defineEmits', () => {
|
||||
expect(() =>
|
||||
compile(`<script setup lang="ts">
|
||||
defineEmits<{
|
||||
foo: []
|
||||
(e: 'hi'): void
|
||||
}>()
|
||||
</script>`)
|
||||
).toThrow(
|
||||
`defineEmits() type cannot mixed call signature and property syntax.`
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -1486,7 +1486,7 @@ export function compileScript(
|
|||
extractRuntimeProps(propsTypeDecl, typeDeclaredProps, declaredTypes)
|
||||
}
|
||||
if (emitsTypeDecl) {
|
||||
extractRuntimeEmits(emitsTypeDecl, typeDeclaredEmits)
|
||||
extractRuntimeEmits(emitsTypeDecl, typeDeclaredEmits, error)
|
||||
}
|
||||
|
||||
// 5. check macro args to make sure it doesn't reference setup scope
|
||||
|
@ -2289,14 +2289,31 @@ function inferValueType(node: Node): string | undefined {
|
|||
|
||||
function extractRuntimeEmits(
|
||||
node: TSFunctionType | TSTypeLiteral | TSInterfaceBody,
|
||||
emits: Set<string>
|
||||
emits: Set<string>,
|
||||
error: (msg: string, node: Node) => never
|
||||
) {
|
||||
if (node.type === 'TSTypeLiteral' || node.type === 'TSInterfaceBody') {
|
||||
const members = node.type === 'TSTypeLiteral' ? node.members : node.body
|
||||
let hasCallSignature = false
|
||||
let hasProperty = false
|
||||
for (let t of members) {
|
||||
if (t.type === 'TSCallSignatureDeclaration') {
|
||||
extractEventNames(t.parameters[0], emits)
|
||||
hasCallSignature = true
|
||||
}
|
||||
if (t.type === 'TSPropertySignature') {
|
||||
if (t.key.type !== 'Identifier' || t.computed) {
|
||||
error(`defineEmits() type cannot use computed keys.`, t.key)
|
||||
}
|
||||
emits.add(t.key.name)
|
||||
hasProperty = true
|
||||
}
|
||||
}
|
||||
if (hasCallSignature && hasProperty) {
|
||||
error(
|
||||
`defineEmits() type cannot mixed call signature and property syntax.`,
|
||||
node
|
||||
)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue