Свойство ‘__docgenInfo’ не существует для типа ‘string’ для дочернего элемента React

#reactjs #typescript

#reactjs #typescript

Вопрос:

Я передаю дочерние элементы компоненту React и использую эту строку кода, чтобы проверить, был ли передан компонент типа ‘Button’ в качестве дочернего элемента.

 export type ExampleComponentProps = {
 children: React.ReactNode;
}

export const ExampleComponent: React.FC<ExampleComponentProps> = ({children}) => { 

const hasButtons = React.Children.toArray(children).some((child) => 
 React.isValidElement(child) amp;amp; child.type._docgenInfo.displayName === 'Button');

console.log(hasButton); //true

 return ( 
  <>{children}</>
 ) 
};

<ExampleComponent>
  <Button>Button</Button>
</ExampleComponent>
 

Я получаю эту ошибку Typescript и, похоже, не могу ее понять.

 Property '__docgenInfo' does not exist on type 'string | JSXElementConstructor<any>'. Property '__docgenInfo' does not exist on type string'. ts(2339)
 

К какому типу я должен привести дочерний элемент, чтобы я мог избавиться от этой ошибки?

Ответ №1:

child.type возвращает строку или JSXElementConstructor, и ни один из них не имеет _docgenInfo свойства ни в одной реализации, которую я смог найти. (Фактически, поиск ‘_docgenInfo’ просто приводит вас к этому вопросу с несколькими другими результатами. Другой результат указывает мне на Storybook, но я ничего не знаю об этой библиотеке / фреймворке, поэтому этот ответ игнорирует эту информацию.)

В любом случае свойство DisplayName в основном используется для отладки. Рекомендуется использовать встроенный класс или идентификатор, чтобы сделать что-то вроде

   const hasButtons = React.Children.toArray(children).some(
    (child) => React.isValidElement(child) amp;amp; child.props.id.includes("valid")
  );
 

Если вы связаны и полны решимости использовать свойство DisplayName, мне удалось получить рабочую версию, приведя свойство type к дочернему FunctionalComponent элементу (потому что тип сам по себе является перенаправленной реакцией ссылкой или чем-то еще; технически это допустимое отображение, но очень схематичное) как таковое:

   const hasDisplayNameButton = React.Children.toArray(children).some(
    (child) => {
      if (React.isValidElement(child)) {
        let t = child.type as React.FunctionComponent;
        return t.displayName === "Button";
      }
      return false;
  });
 

Опять же, я думаю, что такое использование свойства DisplayName не рекомендуется, хотя я не могу найти источники для его резервного копирования.