如何从JSX.Element中提取React函数组件的Props类型?
能否仅通过JSX.Element确定React函数组件的Props类型?
组件及其Props都是本地定义的,虽然能用typeof Test获取类型,但如果只有JSX.Element实例(比如下面的jsxElement),怎么提取对应的Props类型(也就是TestComponentProps)?
示例代码:
import React, { ComponentProps, JSX, ReactElement } from 'react' interface TestComponentProps { onClick: () => void } const Test = ({ onClick }: TestComponentProps) => <button onClick={onClick}>click</button> // 如何仅从该实例提取Props类型/TestComponentProps const jsxElement = <Test onClick={() => 'test' } /> // JSX.Element
我试过下面这些方法,但结果都是any,没法拿到正确类型:
// type foundType = typeof jsxElement.type['props'] // any // type foundType = typeof jsxElement.type // any // type foundType = ComponentProps<typeof jsxElement.props> // any // type foundType = ComponentProps<typeof jsxElement.type> // any // type foundType = ComponentProps<typeof jsxElement.type['props']> // any
直接从JSX.Element实例提取原始组件的Props类型是做不到的。因为编译后的JSX.Element在类型层面,type属性会被降级成宽泛类型(比如FunctionComponent或更通用的类型),丢失了原始组件的具体类型信息;props也只保留了传入的具体值类型,而非组件定义的完整Props接口。
如果非要从JSX.Element反向推导,只能通过间接方式,前提是组件本身的类型信息没被完全擦除:
- 给组件加显式类型标注,保留组件与Props的关联:
const Test: React.FC<TestComponentProps> = ({ onClick }) => <button onClick={onClick}>click</button>
然后用ComponentProps结合类型推断工具:
type ExtractPropsFromElement<E extends JSX.Element> = E extends ReactElement<infer P, infer C> ? ComponentProps<C> : never type FoundType = ExtractPropsFromElement<typeof jsxElement>
不过这种方式依然依赖组件类型是否被正确保留,如果组件是匿名函数或者类型被隐式转换,还是会得到any。
- 用工具函数包裹创建JSX.Element的过程,强制保留类型关联:
function createElementWithProps<C extends React.ComponentType<any>>( component: C, props: React.ComponentProps<C> ): ReactElement<React.ComponentProps<C>, C> { return React.createElement(component, props) } const jsxElement = createElementWithProps(Test, { onClick: () => 'test' }) type FoundType = React.ComponentProps<typeof jsxElement.type>
这种方式能确保jsxElement的类型中保留了原始组件的类型信息,从而正确提取Props。
总结:如果是直接用<Test />这种方式创建的JSX.Element,默认会丢失类型信息,没法直接提取原始Props类型。必须通过显式类型标注或工具函数来保留组件与Props的类型关联,才能实现反向推导。
内容的提问来源于stack exchange,提问作者helion3
相关产品推荐
相关产品推荐

