fix(types): fix functional component for `h` (#9991)

- stricter children/slots type
- fix emits/`EE` type argument of `FunctionalComponent`
This commit is contained in:
三咲智子 Kevin Deng 2024-01-09 16:45:05 +08:00 committed by GitHub
parent 2fd3905738
commit 438a74aad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 4 deletions

View File

@ -2,8 +2,10 @@ import {
type Component, type Component,
type DefineComponent, type DefineComponent,
Fragment, Fragment,
type FunctionalComponent,
Suspense, Suspense,
Teleport, Teleport,
type VNode,
defineComponent, defineComponent,
h, h,
ref, ref,
@ -77,6 +79,19 @@ describe('h inference w/ Suspense', () => {
h(Suspense, { onResolve: 1 }) 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', () => { describe('h inference w/ functional component', () => {
const Func = (_props: { foo: string; bar?: number }) => '' const Func = (_props: { foo: string; bar?: number }) => ''
h(Func, { foo: 'hello' }) h(Func, { foo: 'hello' })
@ -87,6 +102,15 @@ describe('h inference w/ functional component', () => {
h(Func, {}) h(Func, {})
// @ts-expect-error // @ts-expect-error
h(Func, { bar: 123 }) h(Func, { bar: 123 })
h(
fc,
{ foo: 'hello', onClick: () => {} },
{
default: () => vnode,
title: ({ id }: { id: number }) => vnode,
},
)
}) })
describe('h support w/ plain object component', () => { describe('h support w/ plain object component', () => {

View File

@ -10,7 +10,7 @@ import {
} from './vnode' } from './vnode'
import type { Teleport, TeleportProps } from './components/Teleport' import type { Teleport, TeleportProps } from './components/Teleport'
import type { Suspense, SuspenseProps } from './components/Suspense' 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 { RawSlots } from './componentSlots'
import type { import type {
Component, Component,
@ -140,11 +140,11 @@ export function h(
export function h< export function h<
P, P,
E extends EmitsOptions = {}, E extends EmitsOptions = {},
S extends Record<string, any> = {}, S extends Record<string, any> = any,
>( >(
type: FunctionalComponent<P, E, S>, type: FunctionalComponent<P, any, S, any>,
props?: (RawProps & P) | ({} extends P ? null : never), props?: (RawProps & P) | ({} extends P ? null : never),
children?: RawChildren | RawSlots, children?: RawChildren | IfAny<S, RawSlots, S>,
): VNode ): VNode
// catch-all for generic component types // catch-all for generic component types