Проблема с Typescript и eslint при использовании стилизованных компонентов и пользовательского интерфейса Material: `React не распознает реквизит `showText` в элементе DOM`

#reactjs #typescript #material-ui #eslint #styled-components

#reactjs #typescript #material-ui #eslint #стилизованные компоненты

Вопрос:

Я использую компонент в стиле s для возврата Fab компонента material ui, и я получаю следующую ошибку в консоли:

 React does not recognize the `showText` prop on a DOM element.
  If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `showtext` instead
  

Вот компонент:

 import styled from 'styled-components';
import MuiFab from '@material-ui/core/Fab';

type TFabContainer = {
    showText: boolean;
}
const FabContainer = styled(MuiFab)<TFabContainer>`
    width: 250px;
    animation-duration: ${({ showText }) => (showText ? '0.25s' : '1s')};
    animation-iteration-count: linear;
    animation-name: ${({ showText }) => (showText ? expand : contract)};
`;
  

Я знаю, почему возникает это предупреждение, поэтому мне удалось избавиться от него, изменив его на,

 import styled from 'styled-components';
import MuiFab, { FabProps } from '@material-ui/core/Fab';

type TFabContainer = {
    showText: boolean;
    rest: FabProps;
}
const FabContainer = styled(({ showText, ...rest }: TFabContainer) => <MuiFab {...rest} />)`
    width: 250px;
    animation-duration: ${({ showText }) => (showText ? '0.25s' : '1s')};
    animation-iteration-count: linear;
    animation-name: ${({ showText }) => (showText ? expand : contract)};
`;
  

Это устраняет ошибку и корректно отображает мой компонент с ожидаемым поведением, но теперь я получаю 2 предупреждения lint и TS:

 const FabContainer = styled(({ showText, ...rest }: TFabContainer) => <MuiFab {...rest} />)`
                               ^^^^^^^^                                ^^^^^^
'showText' is defined but never used ↑                                  ↑ Property 'href' is missing in type '{ rest: OverrideProps<FabTypeMap<{}, "button">, "button">; }' but required in type '{ href: string; }'.
  

Этих ошибок раньше не было. Также не уверен href , откуда берется prop, это не требуется MuiFab .

Ответ №1:

Это немного раздутый, но на самом деле рекомендуемый способ:

 const FabContainer = styled(({ showText, ...rest }: TFabContainer amp; Omit<MuiFabProps, keyof TFabContainer>)) => <MuiFab {...rest} />)({
    width: 250px;
    animation-duration: ${({ showText }) => (showText ? '0.25s' : '1s')};
    animation-iteration-count: linear;
    animation-name: ${({ showText }) => (showText ? expand : contract)};
});
  

Таким образом, вы сообщаете компилятору, что ваши реквизиты не используются в качестве реквизитов DOM.

Комментарии:

1. Я вижу, это исправило ошибку TS, но не ошибку lint. Я предполагаю, что это просто ложный положительный результат? Возможно, у ESLint возникли проблемы с пониманием стилизованного компонента с литералами шаблона.

2. О, извините, я этого не заметил. Да, точно, вы должны опустить литералы шаблона. Я обновил свой ответ.