From 8876dccf42a7f05375d97cb18c1afdfd0fc51c94 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 30 Mar 2023 19:24:32 +0800 Subject: [PATCH] feat(sfc): support more ergnomic defineEmits type syntax (#7992) --- packages/dts-test/setupHelpers.test-d.ts | 19 +++++++++++++++++++ packages/runtime-core/src/apiSetupHelpers.ts | 20 ++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/dts-test/setupHelpers.test-d.ts b/packages/dts-test/setupHelpers.test-d.ts index a3ab02cab97..d5d332daa1b 100644 --- a/packages/dts-test/setupHelpers.test-d.ts +++ b/packages/dts-test/setupHelpers.test-d.ts @@ -143,6 +143,25 @@ describe('defineEmits w/ type declaration', () => { emit2('baz') }) +describe('defineEmits w/ alt type declaration', () => { + const emit = defineEmits<{ + foo: [id: string] + bar: any[] + baz: [] + }>() + + emit('foo', 'hi') + // @ts-expect-error + emit('foo') + + emit('bar') + emit('bar', 1, 2, 3) + + emit('baz') + // @ts-expect-error + emit('baz', 1) +}) + describe('defineEmits w/ runtime declaration', () => { const emit = defineEmits({ foo: () => {}, diff --git a/packages/runtime-core/src/apiSetupHelpers.ts b/packages/runtime-core/src/apiSetupHelpers.ts index 5ce6fbbd6d1..91f4e39e32e 100644 --- a/packages/runtime-core/src/apiSetupHelpers.ts +++ b/packages/runtime-core/src/apiSetupHelpers.ts @@ -1,4 +1,10 @@ -import { isArray, isPromise, isFunction, Prettify } from '@vue/shared' +import { + isArray, + isPromise, + isFunction, + Prettify, + UnionToIntersection +} from '@vue/shared' import { getCurrentInstance, setCurrentInstance, @@ -120,7 +126,9 @@ export function defineEmits( export function defineEmits( emitOptions: E ): EmitFn -export function defineEmits(): TypeEmit +export function defineEmits< + T extends ((...args: any[]) => any) | Record +>(): T extends (...args: any[]) => any ? T : ShortEmits // implementation export function defineEmits() { if (__DEV__) { @@ -129,6 +137,14 @@ export function defineEmits() { return null as any } +type RecordToUnion> = T[keyof T] + +type ShortEmits> = UnionToIntersection< + RecordToUnion<{ + [K in keyof T]: (evt: K, ...args: T[K]) => void + }> +> + /** * Vue `