I wrote this component for text highlighting:
import { FC } 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: string, index: number, array: string[]) => {
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
It takes filter: string
and str: string
props. Everything working just fine but if I leave everything as it is above I keep getting this error:
Type '({ filter, str }: HighlightProps) => string | (string | Element)[]' is not assignable to type 'FC<HighlightProps>'.
Type 'string | (string | Element)[]' is not assignable to type 'ReactElement<any, any> | null'.
Type 'string' is not assignable to type 'ReactElement<any, any>'.ts(2322)
My question is - how can I properly make typisation for this component and its props?
P.S. I've tried to put s
and str
values in return statements into <>{..}</>
but it did not help.
CodePudding user response:
You have to ensure you are returning proper JSX in all cases.
Now react expects to return a single wrapping Element Node
inside which you can have your children.
Inside the second if
statement, you are returning multiple <span>
elements but without a parent. Just wrap the bit with Fragments too :
import { FC } from "react";
import "./Highlight.css";
type HighlightProps = {
filter: string;
str: string;
};
const Highlight: React.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: string, index: number, array: string[]) => {
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;