'Check if a component is an instance of React.ReactElement<any> in a child map

I have a component that loops through children and wraps them in a div. I am trying to add an exclusion to that, but running into an issue where I can't check if the child is a ReactElement or not (React.ReactChild can be a string, or a number so it may not have a type).

Trying the method below I receive: "'ReactElement' only refers to a type, but is being used as a value here." as well as "Property 'type' does not exist on type 'ReactChild'."

Any help pointing me in the right direction would be greatly appreciated.

  {React.Children.map(children, (child: React.ReactChild) => {
        /**
         * Exclude these components from being
         * wrapped by the item wrapper.
         */
        if (child instanceof React.ReactElement<any> && child.type === Divider) {
          return child;
        }

        if (child) {
          return <div className="l-spacer__item">{React.cloneElement(child as React.ReactElement<any>)}</div>;
        }

        return null;
      })}


Solution 1:[1]

child instanceof React.ReactElement<any>

is invalid because React.ReactElement is not a value. It is an interface. Interfaces are just types, and unlike classes, have no corresponding value. All types are erased. They have no runtime representation.

Furthermore, JavaScript's instanceof is used, and should be understood, as follows

value instanceof anotherValue

This confuses people coming from syntactically similar languages with similarly named operators but wherein the right hand operand is a type. In JavaScript both operands are always values.

To perform your specific check, adjust your code to something along the lines of

if (typeof child !== 'string' && typeof child !== 'number' && child.type === Divider) {
  return child;
}

This works because the type React.ReactChild is defined as

React.ReactElement | React.ReactText;

and React.ReactText is defined as

string | number

By elminating those cases, the language knows it matches the third possible union case, React.ReactElement, which has a type property.

Solution 2:[2]

You should use React.isValidElement. For your case above:

        if (React.isValidElement(child) && child.type === Divider) {
          return child;
        }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 mofojed