@@ -55,6 +55,8 @@ type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N
5555
5656type RawProps = Record < string , any >
5757
58+ type ResolveProps < T > = T extends null | undefined ? T : ( ) => T | T
59+
5860// The following is a series of overloads for providing props validation of
5961// manually written render functions.
6062
@@ -65,15 +67,15 @@ export function h<K extends keyof HTMLElementTagNameMap>(
6567) : Block
6668export function h < K extends keyof HTMLElementTagNameMap > (
6769 type : K ,
68- props ?: ( RawProps & HTMLElementEventHandler ) | null ,
70+ props ?: ResolveProps < RawProps & HTMLElementEventHandler > | null ,
6971 children ?: RawChildren | RawSlots ,
7072) : Block
7173
7274// custom element
7375export function h ( type : string , children ?: RawChildren ) : Block
7476export function h (
7577 type : string ,
76- props ?: RawProps | null ,
78+ props ?: ResolveProps < RawProps > | null ,
7779 children ?: RawChildren | RawSlots ,
7880) : Block
7981
@@ -92,7 +94,7 @@ export function h(
9294export function h ( type : typeof Fragment , children ?: NodeArrayChildren ) : Block
9395export function h (
9496 type : typeof Fragment ,
95- props ?: { key ?: PropertyKey ; ref ?: VNodeRef } | null ,
97+ props ?: ResolveProps < { key ?: PropertyKey ; ref ?: VNodeRef } > | null ,
9698 children ?: NodeArrayChildren ,
9799) : Block
98100
@@ -107,7 +109,7 @@ export function h(
107109export function h ( type : typeof Suspense , children ?: RawChildren ) : Block
108110export function h (
109111 type : typeof Suspense ,
110- props ?: ( RawProps & SuspenseProps ) | null ,
112+ props ?: ResolveProps < RawProps & SuspenseProps > | null ,
111113 children ?: RawChildren | RawSlots ,
112114) : Block
113115
@@ -119,7 +121,7 @@ export function h<
119121 S extends Record < string , any > = any ,
120122> (
121123 type : FunctionalComponent < P , E , S > ,
122- props ?: ( RawProps & P ) | ( { } extends P ? null : never ) ,
124+ props ?: ResolveProps < ( RawProps & P ) | ( { } extends P ? null : never ) > ,
123125 children ?: RawChildren | IfAny < S , RawSlots , S > ,
124126) : Block
125127
@@ -142,16 +144,17 @@ export function h<P>(
142144 | ComponentOptions < P >
143145 | Constructor < P >
144146 | DefineComponent < P > ,
145- props ?: ( RawProps & P ) | ( { } extends P ? null : never ) ,
147+ props ?: ResolveProps < ( RawProps & P ) | ( { } extends P ? null : never ) > ,
146148 children ?: RawChildren | RawSlots ,
147149) : Block
148150
149151export function h ( type : any , propsOrChildren ?: any , children ?: any ) {
150152 const l = arguments . length
151153 if ( l === 2 ) {
152154 if (
153- typeof propsOrChildren === 'object' &&
154- ! Array . isArray ( propsOrChildren )
155+ ( typeof propsOrChildren === 'object' &&
156+ ! Array . isArray ( propsOrChildren ) ) ||
157+ typeof propsOrChildren === 'function'
155158 ) {
156159 // single block without props
157160 if ( isBlock ( propsOrChildren ) ) {
@@ -161,10 +164,7 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
161164 }
162165
163166 // props without children
164- return createComponentWithFallback (
165- type ,
166- propsOrChildren ? { $ : [ ( ) => propsOrChildren ] } : null ,
167- )
167+ return createComponentWithFallback ( type , resolveProps ( propsOrChildren ) )
168168 } else {
169169 // omit props
170170 return createComponentWithFallback ( type , null , {
@@ -177,7 +177,7 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
177177 }
178178 return createComponentWithFallback (
179179 type ,
180- propsOrChildren ? { $ : [ ( ) => propsOrChildren ] } : null ,
180+ resolveProps ( propsOrChildren ) ,
181181 children
182182 ? typeof children === 'object' && ! Array . isArray ( children )
183183 ? children
@@ -188,3 +188,24 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
188188 )
189189 }
190190}
191+
192+ function resolveProps (
193+ props ?: Record < string , any > | ( ( ) => Record < string , any > ) ,
194+ ) {
195+ if ( props ) {
196+ if ( typeof props === 'function' ) {
197+ return { $ : [ props ] }
198+ }
199+ const resolvedProps : Record < string , any > = { }
200+ // eslint-disable-next-line no-restricted-syntax
201+ for ( const key in props ) {
202+ if ( typeof props [ key ] === 'function' || key === '$' ) {
203+ resolvedProps [ key ] = props [ key ]
204+ } else {
205+ resolvedProps [ key ] = ( ) => props [ key ]
206+ }
207+ }
208+ return resolvedProps
209+ }
210+ return null
211+ }
0 commit comments