types(defineComponent): Keep slot information on functional components

This commit is contained in:
Carlos Rodrigues 2023-11-30 15:29:57 +00:00
parent dd26e98233
commit e8f693eda6
3 changed files with 53 additions and 4 deletions

View File

@ -1497,6 +1497,41 @@ describe('should work when props type is incompatible with setup returned type '
expectType<SizeType>(CompA.$props.size)
})
// #9649
describe('should keep slots on functional component', () => {
const Comp = defineComponent(
(
_1: {},
_2: SetupContext<
{},
SlotsType<{ default?(data: { foo: string; bar: number }): any }>
>
) =>
() =>
null,
{
slots: Object as SlotsType<{ default: { foo: string; bar: number } }>
}
)
h(Comp, {
default: data => {
expectType<{ foo: string; bar: number }>(data)
// @ts-expect-error not any
expectType<string>(data)
return null
}
})
h(Comp, null, {
default: data => {
expectType<{ foo: string; bar: number }>(data)
// @ts-expect-error not any
expectType<string>(data)
return null
}
})
})
import {
DefineComponent,
ComponentOptionsMixin,

View File

@ -111,7 +111,7 @@ export function defineComponent<
emits?: E | EE[]
slots?: S
}
): (props: Props & EmitsToProps<E>) => any
): (props: Props & EmitsToProps<E> & S) => any
export function defineComponent<
Props extends Record<string, any>,
E extends EmitsOptions = {},
@ -127,7 +127,7 @@ export function defineComponent<
emits?: E | EE[]
slots?: S
}
): (props: Props & EmitsToProps<E>) => any
): (props: Props & EmitsToProps<E> & S) => any
// overload 2: object format with no props
// (uses user defined props interface)

View File

@ -11,7 +11,7 @@ import {
import { Teleport, TeleportProps } from './components/Teleport'
import { Suspense, SuspenseProps } from './components/Suspense'
import { isObject, isArray } from '@vue/shared'
import { RawSlots } from './componentSlots'
import { RawSlots, SlotsType, UnwrapSlotsType } from './componentSlots'
import {
FunctionalComponent,
Component,
@ -119,6 +119,17 @@ export function h(
children?: RawChildren | RawSlots
): VNode
// functional component
export function h<
P,
E extends EmitsOptions = {},
S extends Record<string, any> = {}
>(
type: FunctionalComponent<P, E, S>,
children?:
| RawChildren
| (P extends SlotsType<any> ? UnwrapSlotsType<P> : never)
): VNode
// functional component
export function h<
P,
@ -127,7 +138,10 @@ export function h<
>(
type: FunctionalComponent<P, E, S>,
props?: (RawProps & P) | ({} extends P ? null : never),
children?: RawChildren | RawSlots
children?:
| RawChildren
| RawSlots
| (P extends SlotsType<any> ? UnwrapSlotsType<P> : {})
): VNode
// catch-all for generic component types