React+TypeScript报错:Element[]无法赋值给ReactElement类型的解决方法
React组件children类型不匹配问题解决
问题场景
你声明的Wrapper组件类型定义如下:
import { ReactElement } from 'react'; const Wrapper = ({children}: {children: ReactElement[]}): ReactElement => { return ( <div className="wrapper"> {children} </div> ); };
当仅传入map返回的元素数组时,代码可正常运行:
<Wrapper> {items.map((item, index) => { return ( <Item /> ) })} </Wrapper>
但混合直接书写的元素与map结果时,出现TypeScript报错:
<Wrapper> <div /> {/* empty div for the first column */} {items.map((item, index) => { return ( <Item /> ) })} </Wrapper>
报错信息:
Type 'Element[]' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'.ts(2322)
原因分析
React处理混合写法的子元素时,会将单个元素(如<div />)与map返回的元素数组合并,但你的组件定义要求children必须是ReactElement[]类型,而TypeScript会将混合写法的子元素推断为Element | Element[],导致类型不匹配。
解决方法
方法一:改用React标准的ReactNode类型(推荐)
ReactNode是React官方定义的合法子元素类型,包含单个元素、数组、文本、null等所有合法情况,修改组件类型定义即可:
import { ReactElement, ReactNode } from 'react'; const Wrapper = ({children}: {children: ReactNode}): ReactElement => { return ( <div className="wrapper"> {children} </div> ); };
方法二:将所有子元素包裹为标准数组
若需保持ReactElement[]类型要求,可将直接书写的元素与map结果合并为一个数组,同时为每个元素添加唯一key(React列表元素必填):
<Wrapper> {[ <div key="empty-column" />, ...items.map((item, index) => ( <Item key={item.id} /> // 优先使用item的唯一标识作为key,避免用index )) ]} </Wrapper>
方法三:调整为联合类型
如果组件需要同时支持单个元素和元素数组,可将children类型改为联合类型:
import { ReactElement } from 'react'; const Wrapper = ({children}: {children: ReactElement | ReactElement[]}): ReactElement => { return ( <div className="wrapper"> {children} </div> ); };
注:该方式灵活性不如ReactNode,无法支持文本、null等其他合法子元素。
内容的提问来源于stack exchange,提问作者Renaud is Not Bill Gates
相关产品推荐
相关产品推荐

