升级@types/react至18.0.0后React.createElement类型匹配错误排查
React 18泛型ComponentClass类型不兼容错误分析与解决
问题根源
React 18对@types/react的类型定义进行了收紧,尤其是ComponentClass与React.createElement的类型匹配逻辑。当调用React.createElement(component)且未传递props时,TypeScript会默认推断组件接收的props类型为{},但你的component是ComponentClass<MyProps>类型——它的getDerivedStateFromProps方法期望接收MyProps类型的参数,而非{},这就触发了类型不兼容错误:Readonly<{}>无法赋值给Readonly<MyProps>。
临时修复的原理
你添加的MyProps extends {}约束,本质是告知TypeScript:MyProps是{}的子类型(即任意对象类型)。此时ComponentClass<MyProps>可被视为ComponentClass<{}>的子类型,子类型组件的props要求不会比父类型更严格,从而绕过了类型检查。但这只是妥协方案,并非最严谨的解决方式。
正确解决方法
方法1:明确props参数类型,匹配组件要求
修改createElement函数,让props参数类型与组件的MyProps匹配,同时允许可选传递:
class Test extends React.Component { render() { // 若Text组件需要MyProps,此处传递对应props;否则传undefined/{} return this.createElement(Text, {}); } createElement<MyProps>(component: ComponentClass<MyProps>, props?: Partial<MyProps>) { return React.createElement(component, props); } }
TypeScript能正确推断组件的props类型,避免不兼容问题。
方法2:约束组件props允许空值
如果组件确实不需要任何props,直接约束MyProps为{}即可:
class Test extends React.Component { render() { return this.createElement(Text); } createElement<MyProps = {}>(component: ComponentClass<MyProps>) { return React.createElement(component); } }
方法3:显式断言props类型(不推荐,仅适用于特殊场景)
若确定组件可接收空props,可通过类型断言跳过检查:
createElement<MyProps>(component: ComponentClass<MyProps>) { return React.createElement(component, {} as MyProps); }
内容的提问来源于stack exchange,提问作者Keer
相关产品推荐
相关产品推荐

