From 0d6afa81045901bed87a70bba73edc5e4bfd4e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Thu, 4 Jan 2024 17:09:17 +0800 Subject: [PATCH 1/2] types: fix functional component for `h` - stricter children/slots type - fix emits/`EE` type argument of `FunctionalComponent` --- packages/runtime-core/src/h.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/src/h.ts b/packages/runtime-core/src/h.ts index d683a288c26..93e7fd9bc88 100644 --- a/packages/runtime-core/src/h.ts +++ b/packages/runtime-core/src/h.ts @@ -10,7 +10,7 @@ import { } from './vnode' import type { Teleport, TeleportProps } from './components/Teleport' import type { Suspense, SuspenseProps } from './components/Suspense' -import { isArray, isObject } from '@vue/shared' +import { type IfAny, isArray, isObject } from '@vue/shared' import type { RawSlots } from './componentSlots' import type { Component, @@ -140,11 +140,11 @@ export function h( export function h< P, E extends EmitsOptions = {}, - S extends Record = {}, + S extends Record = any, >( - type: FunctionalComponent, + type: FunctionalComponent, props?: (RawProps & P) | ({} extends P ? null : never), - children?: RawChildren | RawSlots, + children?: RawChildren | IfAny, ): VNode // catch-all for generic component types From b47844b3df0c31e3ef338d7d2caf3c3f53037f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Thu, 4 Jan 2024 17:20:38 +0800 Subject: [PATCH 2/2] test: add h --- packages/dts-test/h.test-d.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/dts-test/h.test-d.ts b/packages/dts-test/h.test-d.ts index 62e619c22bd..a199e14ced9 100644 --- a/packages/dts-test/h.test-d.ts +++ b/packages/dts-test/h.test-d.ts @@ -2,8 +2,10 @@ import { type Component, type DefineComponent, Fragment, + type FunctionalComponent, Suspense, Teleport, + type VNode, defineComponent, h, ref, @@ -77,6 +79,19 @@ describe('h inference w/ Suspense', () => { h(Suspense, { onResolve: 1 }) }) +declare const fc: FunctionalComponent< + { + foo: string + bar?: number + onClick: (evt: MouseEvent) => void + }, + ['click'], + { + default: () => VNode + title: (scope: { id: number }) => VNode + } +> +declare const vnode: VNode describe('h inference w/ functional component', () => { const Func = (_props: { foo: string; bar?: number }) => '' h(Func, { foo: 'hello' }) @@ -87,6 +102,15 @@ describe('h inference w/ functional component', () => { h(Func, {}) // @ts-expect-error h(Func, { bar: 123 }) + + h( + fc, + { foo: 'hello', onClick: () => {} }, + { + default: () => vnode, + title: ({ id }: { id: number }) => vnode, + }, + ) }) describe('h support w/ plain object component', () => {