Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

styled-components typescript error with Material-UI component

Using typescript and want to set styling for Material UI component with styled-components.
But type error happens with StyledComponent showing Type '{ children: string; }' is missing the following properties

import React, { PureComponent } from 'react';
import styled from 'styled-components'; // ^4.1.3
import { Button } from '@material-ui/core'; // ^3.9.1

class TestForm extends PureComponent {
  render() {
    return (
      <>
        <Button style={{ backgroundColor: 'red' }}>Work</Button>{/* OK  */}

        <StyledButton>Doesn't work</StyledButton>{/* Type Error happens here <=============== */}
        {/**
          Type '{ children: string; }' is missing the following properties from type 'Pick<Pick<(ButtonProps & RefAttributes<Component<ButtonProps, any, any>>) | (ButtonProps & { children?: ReactNode; }), "form" | "style" | "title" | "disabled" | "mini" | ... 279 more ... | "variant"> & Partial<...>, "form" | ... 283 more ... | "variant">': style, classes, className, innerRef [2739]
         */}
      </>
    );
  }
}

const StyledButton = styled(Button)`
  background: blue;
`;

export default TestForm;

It is showing children prop is missing.
I have tried the following too but still doesn't work.

const StyledButton = styled(Button)<{ children: string; }>`
  background: blue;
`;

Does anyone know how to use Material UI with styled-components in typescript?

like image 639
Thu San Avatar asked Feb 04 '19 03:02

Thu San


1 Answers

I'm also getting this error with material-ui v3.9.3 and styled-components v4.2.0, the latest versions at the time of posting this answer.

My workaround for this is the following

import styled from 'styled-components'
import Button, { ButtonProps } from '@material-ui/core/Button'

const StyledButton = styled(Button)`
  background: blue;
` as React.ComponentType<ButtonProps>

This casts StyledButton to the same type as the Material UI Button. It removes the error and gives you the same type checking as you get for Button. In most cases this is all you want.

In cases where you need additional props to use in the styles, and want to enforce they are passed, you can just extend ButtonProps and cast to that custom type:

type StyledButtonProps = ButtonProps & { background: string }

const StyledButton = styled(Button)`
  background: ${(props: StyledButtonProps) => props.background};
` as React.ComponentType<StyledButtonProps>


const MyComponent = () => (
  <div>
    <StyledButton size='small' background='blue'>one</StyledButton>

    // ERROR HERE - forgot the 'background' prop
    <StyledButton size='small'>two</StyledButton>
  </div>
)
like image 104
davnicwil Avatar answered Sep 28 '22 01:09

davnicwil