}"
`;
-exports[`SFC compile <script setup> with TypeScript defineEmit w/ type (union) 1`] = `
+exports[`SFC compile <script setup> with TypeScript defineEmit w/ type (type literal w/ call signatures) 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
expose: [],
emits: [\\"foo\\", \\"bar\\", \\"baz\\"] as unknown as undefined,
setup(__props, { emit }: {
- emit: (((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)),
+ emit: ({(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}),
slots: any,
attrs: any
}) {
test('defineEmit w/ type (union)', () => {
const type = `((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)`
+ expect(() =>
+ compile(`
+ <script setup lang="ts">
+ import { defineEmit } from 'vue'
+ const emit = defineEmit<${type}>()
+ </script>
+ `)
+ ).toThrow()
+ })
+
+ test('defineEmit w/ type (type literal w/ call signatures)', () => {
+ const type = `{(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}`
const { content } = compile(`
<script setup lang="ts">
import { defineEmit } from 'vue'
Statement,
Expression,
LabeledStatement,
- TSUnionType,
- CallExpression
+ CallExpression,
+ RestElement
} from '@babel/types'
import { walk } from 'estree-walker'
import { RawSourceMap } from 'source-map'
let propsTypeDecl: TSTypeLiteral | undefined
let propsIdentifier: string | undefined
let emitRuntimeDecl: Node | undefined
- let emitTypeDecl: TSFunctionType | TSUnionType | undefined
+ let emitTypeDecl: TSFunctionType | TSTypeLiteral | undefined
let emitIdentifier: string | undefined
let hasAwait = false
let hasInlinedSsrRenderFn = false
const typeArg = node.typeParameters.params[0]
if (
typeArg.type === 'TSFunctionType' ||
- typeArg.type === 'TSUnionType'
+ typeArg.type === 'TSTypeLiteral'
) {
emitTypeDecl = typeArg
} else {
error(
`type argument passed to ${DEFINE_EMIT}() must be a function type ` +
- `or a union of function types.`,
+ `or a literal type with call signatures.`,
typeArg
)
}
}
function extractRuntimeEmits(
- node: TSFunctionType | TSUnionType,
+ node: TSFunctionType | TSTypeLiteral,
emits: Set<string>
) {
- if (node.type === 'TSUnionType') {
- for (let t of node.types) {
- if (t.type === 'TSParenthesizedType') t = t.typeAnnotation
- if (t.type === 'TSFunctionType') {
- extractRuntimeEmits(t, emits)
+ if (node.type === 'TSTypeLiteral') {
+ for (let t of node.members) {
+ if (t.type === 'TSCallSignatureDeclaration') {
+ extractEventNames(t.parameters[0], emits)
}
}
return
+ } else {
+ extractEventNames(node.parameters[0], emits)
}
+}
- const eventName = node.parameters[0]
+function extractEventNames(
+ eventName: Identifier | RestElement,
+ emits: Set<string>
+) {
if (
eventName.type === 'Identifier' &&
eventName.typeAnnotation &&