1

I try to dynamically check in typescript the types of react children components. The following code is working pretty well, however seems typescript does not want me to destructure children.

I get the Typescript error :

TS2339: Property 'type' does not exist on type 'ReactNode'.

What can i do t get rid of the typescript error instead of using // @ts-ignore.

import * as React from 'react';

    export interface AuxProps  { 
      children: React.ReactNode[]
    }

    export const Message: React.FC<AuxProps> = ({
      children,
    }: AuxProps) => {
      
      const test = children.filter(({ type }) => type === Test);

      return (
        <div>
          {test}
        <div/>
      );
    };

2 Answers 2

1

This is because the default ReactNode does not have the field type.

You can simply add that key by using the & functionality:

export interface AuxProps  { 
      children: (React.ReactNode & {type: string})[]
    }

This will add the type to the elements.

Sign up to request clarification or add additional context in comments.

2 Comments

Yea thanks that works but one additional question. If i check : type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined; and type ReactChild = ReactElement | ReactText; interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> { type: T; props: P; key: Key | null; } so actually it should be there already or not?
Great, can you accept the answer if that fixes your problem. This is because it could be both and only the second has the type and not the first one. So only one half has it and it can be, that the Node does not have it. IF you use the ReactChild insteda, that should work
1

You can't read type from ReactChild, because ReactChild is a union and not every member of that union has a property called type.

In fact, only ReactElements do.

The solution is to check for two things inside your predicate function:

  • Is this child a ReactElement?
  • If yes, then is that element of the desired type?

Code:

const test = children.filter(child => React.isValidElement(child) && child.type === 'Test');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.