Typescript and eslint issue when using styled-components and Material UI: `React does not recognize the `showText` prop on a DOM element`

Viewed 678

I'm using s styled component to return a material ui Fab component, and I get the following error in the console:

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

Here is the component:

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)};
`;

I know why this warning is occurring, so I managed to get rid of it by changing it to,

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)};
`;

This gets rid of the error and correctly render my component with the expected behaviour, but now I'm getting 2 lint and TS warnings thrown:

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; }'.

These errors weren't here before. Not sure where the href prop is coming from either, it's not required in MuiFab.

1 Answers

It's a bit bloated, but actually the recommended way:

const FabContainer = styled(({ showText, ...rest }: TFabContainer & 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)};
});

This way you are telling the compiler that your props aren't used as DOM props.

Related