Skip to content

Commit 3b8a4cb

Browse files
committed
feat(core): enhance NodeProps type to conditionally include built-in React components
1 parent e91e48f commit 3b8a4cb

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

src/core.node.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ export function createNode<AdditionalInitialProps extends Record<string, any>, E
546546
Node(element, { ...initialProps, ...props } as NodeProps<E> & AdditionalProps)
547547

548548
Instance.element = element
549-
return Instance
549+
return Instance as any
550550
}
551551

552552
/**
@@ -570,5 +570,5 @@ export function createChildrenFirstNode<AdditionalInitialProps extends Record<st
570570
) => Node(element, { ...initialProps, ...props, children } as NodeProps<E> & AdditionalProps)
571571

572572
Instance.element = element
573-
return Instance
573+
return Instance as any
574574
}

src/node.type.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import React, {
88
type Component,
99
type ExoticComponent,
1010
type ReactElement,
11+
type FragmentProps,
12+
type SuspenseProps,
13+
type ActivityProps,
1114
} from 'react'
1215
import type { NO_STYLE_TAGS } from '@src/constants/common.const.js'
1316
import type { ComponentNodeProps } from '@src/hoc/component.hoc.js'
@@ -27,6 +30,13 @@ export interface ReactAttributes {
2730
key?: string
2831
}
2932

33+
/**
34+
* Type guard to check if a given element is a built-in React component (Fragment, Suspense, Activity).
35+
* @template E - The element type to check
36+
*/
37+
export type IsReactBuiltInComponent<E> =
38+
E extends ExoticComponent<FragmentProps> ? true : E extends ExoticComponent<SuspenseProps> ? true : E extends ExoticComponent<ActivityProps> ? true : false
39+
3040
/**
3141
* Excludes array types from ReactNode, ensuring a single, non-array React element or primitive.
3242
*/
@@ -206,15 +216,23 @@ export type HasNoStyleProp<E extends NodeElement> = E extends NoStyleTags ? true
206216
* - Maintains React's key prop for reconciliation
207217
* @template E - The element type these props apply to
208218
*/
209-
export type NodeProps<E extends NodeElement> = Omit<PropsOf<E>, keyof CSSProperties | 'children' | 'style' | 'props' | 'key'> &
210-
ReactAttributes &
211-
(HasCSSCompatibleStyleProp<PropsOf<E>> extends true ? ThemedCSSProperties : object) &
212-
(HasNoStyleProp<E> extends false ? Partial<{ css: CssProp }> : object) &
213-
Partial<{
214-
disableEmotion: boolean
215-
props: Partial<Omit<PropsOf<E>, 'children'>>
216-
children: Children
217-
}>
219+
export type NodeProps<E extends NodeElement> =
220+
IsReactBuiltInComponent<E> extends false
221+
? Omit<PropsOf<E>, keyof CSSProperties | 'children' | 'style' | 'props' | 'key'> &
222+
ReactAttributes &
223+
(HasCSSCompatibleStyleProp<PropsOf<E>> extends true ? ThemedCSSProperties : object) &
224+
(HasNoStyleProp<E> extends false ? Partial<{ css: CssProp }> : object) &
225+
Partial<{
226+
disableEmotion: boolean
227+
props: Partial<Omit<PropsOf<E>, 'children'>>
228+
children: Children
229+
}>
230+
: PropsOf<E> &
231+
ReactAttributes &
232+
Partial<{
233+
disableEmotion: boolean
234+
children: Children
235+
}>
218236

219237
/**
220238
* Function type for dynamic node content generation.

0 commit comments

Comments
 (0)