React FC组件TS类型不匹配报错如何正确定义类型?
报错原因
FC类型在旧版本@types/react的定义中,强制要求组件返回值必须是ReactElement | null,不接受字符串、数组这类合法的React渲染值。你的代码里有3处直接返回裸字符串的分支:
- 无过滤值时直接
return str - 无匹配结果时直接
return str - split后map遍历的最后一项直接
return s
之前尝试用Fragment包裹没生效,是因为没有把所有返回裸字符串的分支都覆盖到,只要有一个分支不符合类型要求,TS就会抛错。
修复方案
两种方案选其一即可:
方案1:全分支返回React元素(兼容所有版本类型定义)
把所有裸返回字符串的位置都用Fragment包裹,保证所有代码路径都返回合法React元素,完全符合FC的类型约束:
import { FC, Fragment } from 'react' import './Highlight.css' interface HighlightProps { filter: string str: string } const Highlight: FC<HighlightProps> = ({filter, str}) =>{ if (!filter) return <>{str}</> const regexp = new RegExp(filter, 'ig') const matchValue = str.match(regexp) if (matchValue) { return ( <> {str.split(regexp).map((s, index, array) => { if (index < array.length - 1) { const overlap = matchValue.shift() return ( <Fragment key={index}> {s}<span className='highlight'>{overlap}</span> </Fragment> ) } return <Fragment key={index}>{s}</Fragment> })} </> ) } return <>{str}</> } export default Highlight
方案2:调整返回值类型定义(代码更简洁)
放弃使用FC做组件类型约束,直接显式标注组件返回值为React.ReactNode。这个类型本身就覆盖了字符串、数字、React元素、Fragment、null等所有React支持的合法返回值,不需要额外包裹元素:
import { ReactNode } from 'react' import './Highlight.css' interface HighlightProps { filter: string str: string } const Highlight = ({filter, str}: HighlightProps): ReactNode =>{ if (!filter) return str const regexp = new RegExp(filter, 'ig') const matchValue = str.match(regexp) if (matchValue) { return str.split(regexp).map((s, index, array) => { if (index < array.length - 1) { const overlap = matchValue.shift() return ( <span key={index}> {s}<span className='highlight'>{overlap}</span> </span> ) } return s }) } return str } export default Highlight
额外优化提示
当前直接把filter传入RegExp构造的写法有逻辑隐患:如果filter字符串中包含(、.、*、?这类正则特殊字符,会导致正则匹配异常,建议使用前先对filter做正则特殊字符转义处理。
内容的提问来源于stack exchange,提问作者Ilya Kruchinin
相关产品推荐
相关产品推荐

