@@ -55,6 +55,8 @@ type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N
55
55
56
56
type RawProps = Record < string , any >
57
57
58
+ type ResolveProps < T > = T extends null | undefined ? T : ( ) => T | T
59
+
58
60
// The following is a series of overloads for providing props validation of
59
61
// manually written render functions.
60
62
@@ -65,15 +67,15 @@ export function h<K extends keyof HTMLElementTagNameMap>(
65
67
) : Block
66
68
export function h < K extends keyof HTMLElementTagNameMap > (
67
69
type : K ,
68
- props ?: ( RawProps & HTMLElementEventHandler ) | null ,
70
+ props ?: ResolveProps < RawProps & HTMLElementEventHandler > | null ,
69
71
children ?: RawChildren | RawSlots ,
70
72
) : Block
71
73
72
74
// custom element
73
75
export function h ( type : string , children ?: RawChildren ) : Block
74
76
export function h (
75
77
type : string ,
76
- props ?: RawProps | null ,
78
+ props ?: ResolveProps < RawProps > | null ,
77
79
children ?: RawChildren | RawSlots ,
78
80
) : Block
79
81
@@ -92,7 +94,7 @@ export function h(
92
94
export function h ( type : typeof Fragment , children ?: NodeArrayChildren ) : Block
93
95
export function h (
94
96
type : typeof Fragment ,
95
- props ?: { key ?: PropertyKey ; ref ?: VNodeRef } | null ,
97
+ props ?: ResolveProps < { key ?: PropertyKey ; ref ?: VNodeRef } > | null ,
96
98
children ?: NodeArrayChildren ,
97
99
) : Block
98
100
@@ -107,7 +109,7 @@ export function h(
107
109
export function h ( type : typeof Suspense , children ?: RawChildren ) : Block
108
110
export function h (
109
111
type : typeof Suspense ,
110
- props ?: ( RawProps & SuspenseProps ) | null ,
112
+ props ?: ResolveProps < RawProps & SuspenseProps > | null ,
111
113
children ?: RawChildren | RawSlots ,
112
114
) : Block
113
115
@@ -119,7 +121,7 @@ export function h<
119
121
S extends Record < string , any > = any ,
120
122
> (
121
123
type : FunctionalComponent < P , E , S > ,
122
- props ?: ( RawProps & P ) | ( { } extends P ? null : never ) ,
124
+ props ?: ResolveProps < ( RawProps & P ) | ( { } extends P ? null : never ) > ,
123
125
children ?: RawChildren | IfAny < S , RawSlots , S > ,
124
126
) : Block
125
127
@@ -142,16 +144,17 @@ export function h<P>(
142
144
| ComponentOptions < P >
143
145
| Constructor < P >
144
146
| DefineComponent < P > ,
145
- props ?: ( RawProps & P ) | ( { } extends P ? null : never ) ,
147
+ props ?: ResolveProps < ( RawProps & P ) | ( { } extends P ? null : never ) > ,
146
148
children ?: RawChildren | RawSlots ,
147
149
) : Block
148
150
149
151
export function h ( type : any , propsOrChildren ?: any , children ?: any ) {
150
152
const l = arguments . length
151
153
if ( l === 2 ) {
152
154
if (
153
- typeof propsOrChildren === 'object' &&
154
- ! Array . isArray ( propsOrChildren )
155
+ ( typeof propsOrChildren === 'object' &&
156
+ ! Array . isArray ( propsOrChildren ) ) ||
157
+ typeof propsOrChildren === 'function'
155
158
) {
156
159
// single block without props
157
160
if ( isBlock ( propsOrChildren ) ) {
@@ -161,10 +164,7 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
161
164
}
162
165
163
166
// props without children
164
- return createComponentWithFallback (
165
- type ,
166
- propsOrChildren ? { $ : [ ( ) => propsOrChildren ] } : null ,
167
- )
167
+ return createComponentWithFallback ( type , resolveProps ( propsOrChildren ) )
168
168
} else {
169
169
// omit props
170
170
return createComponentWithFallback ( type , null , {
@@ -177,7 +177,7 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
177
177
}
178
178
return createComponentWithFallback (
179
179
type ,
180
- propsOrChildren ? { $ : [ ( ) => propsOrChildren ] } : null ,
180
+ resolveProps ( propsOrChildren ) ,
181
181
children
182
182
? typeof children === 'object' && ! Array . isArray ( children )
183
183
? children
@@ -188,3 +188,24 @@ export function h(type: any, propsOrChildren?: any, children?: any) {
188
188
)
189
189
}
190
190
}
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