-->

styled-components typescript error with Material-U

2020-06-17 05:39发布

问题:

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?

回答1:

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>
)


回答2:

This was working fine a few months ago, but I just started a new project and am having the same issue. Must be a problem with the more recent versions.

Horrible, I know, but in the meantime maybe best to:

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