Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problem with functional component typisation

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

P.S. I’ve tried to put s and str values in return statements into <>{..}</> but it did not help.

>Solution :

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;

Sandbox

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading