Skip to content

Commit 8876dcc

Browse files
authored
feat(sfc): support more ergnomic defineEmits type syntax (#7992)
1 parent 8ac0620 commit 8876dcc

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

packages/dts-test/setupHelpers.test-d.ts

+19
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,25 @@ describe('defineEmits w/ type declaration', () => {
143143
emit2('baz')
144144
})
145145

146+
describe('defineEmits w/ alt type declaration', () => {
147+
const emit = defineEmits<{
148+
foo: [id: string]
149+
bar: any[]
150+
baz: []
151+
}>()
152+
153+
emit('foo', 'hi')
154+
// @ts-expect-error
155+
emit('foo')
156+
157+
emit('bar')
158+
emit('bar', 1, 2, 3)
159+
160+
emit('baz')
161+
// @ts-expect-error
162+
emit('baz', 1)
163+
})
164+
146165
describe('defineEmits w/ runtime declaration', () => {
147166
const emit = defineEmits({
148167
foo: () => {},

packages/runtime-core/src/apiSetupHelpers.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { isArray, isPromise, isFunction, Prettify } from '@vue/shared'
1+
import {
2+
isArray,
3+
isPromise,
4+
isFunction,
5+
Prettify,
6+
UnionToIntersection
7+
} from '@vue/shared'
28
import {
39
getCurrentInstance,
410
setCurrentInstance,
@@ -120,7 +126,9 @@ export function defineEmits<EE extends string = string>(
120126
export function defineEmits<E extends EmitsOptions = EmitsOptions>(
121127
emitOptions: E
122128
): EmitFn<E>
123-
export function defineEmits<TypeEmit>(): TypeEmit
129+
export function defineEmits<
130+
T extends ((...args: any[]) => any) | Record<string, any[]>
131+
>(): T extends (...args: any[]) => any ? T : ShortEmits<T>
124132
// implementation
125133
export function defineEmits() {
126134
if (__DEV__) {
@@ -129,6 +137,14 @@ export function defineEmits() {
129137
return null as any
130138
}
131139

140+
type RecordToUnion<T extends Record<string, any>> = T[keyof T]
141+
142+
type ShortEmits<T extends Record<string, any>> = UnionToIntersection<
143+
RecordToUnion<{
144+
[K in keyof T]: (evt: K, ...args: T[K]) => void
145+
}>
146+
>
147+
132148
/**
133149
* Vue `<script setup>` compiler macro for declaring a component's exposed
134150
* instance properties when it is accessed by a parent component via template

0 commit comments

Comments
 (0)