TypeScript中动态渲染HTML组件及Props类型定义问题
React组件兼容自定义组件与原生HTML标签的TypeScript处理方案
问题描述
以下组件代码中,当传入"span"作为Component属性时,TypeScript会报错:
interface MyComponentProps { Component: React.ComponentType } const MyComponent: React.FC<PropsWithChildren<MyComponentProps>> = ({Component, children}) => { return <Component>{children}</Component> } <MyComponent Component="span" />
报错信息:
Type 'string' is not assignable to type 'ComponentType<{}> | undefined'.
需要实现:让Component属性既能接受自定义React组件,也能接受原生HTML标签名(字符串),同时保证TypeScript类型校验通过,且能正确渲染。
解决步骤
1. 替换Props类型为ElementType
React内置了ElementType类型,它已包含所有原生HTML标签名(字符串类型)和自定义组件(ComponentType)的联合类型,直接用它定义Component属性即可:
import type { PropsWithChildren, ElementType } from 'react'; interface MyComponentProps { Component: ElementType; }
2. 组件渲染逻辑无需改动
原有的渲染代码可以直接复用,React会自动识别Component是原生标签还是自定义组件并正确渲染:
const MyComponent: React.FC<PropsWithChildren<MyComponentProps>> = ({ Component, children }) => { return <Component>{children}</Component>; };
3. 两种用法示例
现在组件支持两种传参方式:
// 传入原生HTML标签 <MyComponent Component="span">这是一个span标签的内容</MyComponent> // 传入自定义组件 const CustomCard = ({ children }: PropsWithChildren) => ( <div className="card">{children}</div> ); <MyComponent Component={CustomCard}>这是自定义卡片的内容</MyComponent>
为什么这样可行?
ElementType的本质是string | ComponentType<any>,刚好覆盖了原生标签名和React组件的类型范围,TypeScript会自动做类型校验,而React在渲染时遇到字符串类型的组件名,会自动创建对应的原生DOM元素。
内容的提问来源于stack exchange,提问作者Moritz Roessler
相关产品推荐
相关产品推荐

