0

I'm new to react and currently started a learning project, In which I'm using typescript 3.7.2 with material-ui 4.11.0 and react 16.13.1. I've created all my page layouts as functional components but upon trying to convert them to class components (I find it easier than using hooks) I get the following errors (attached as comments), I've looked at some other answers on stackoverflow and tried different approaches but none seem to work, most of the answers I've read through are 2-3 years back and I guessed some of the changes since then were breaking changes, does anyone knows how to solve those?

import React from "react";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
import Link from "@material-ui/core/Link";
import Grid from "@material-ui/core/Grid";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import Typography from "@material-ui/core/Typography";
import { makeStyles, withStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";

const styles = makeStyles((theme) => ({
  paper: {
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main,
  },
  form: {
    width: "100%", // Fix IE 11 issue.
    marginTop: theme.spacing(1),
    marginBottom: theme.spacing(15),
  },
  submit: {
    margin: theme.spacing(3, 0, 2),
  },
}));

class LoginPage extends React.Component {
  render() {
    // Next line is first problem - I get :
    // **"Property 'classes' does not exist on type 'Readonly<{}> & Readonly<{ children?: ReactNode; }>'.ts(2339)"**
    const { classes } = this.props;
    return (
      <Container component="main" maxWidth="xs">
        <CssBaseline />
        <div className={classes.paper}>
          <Avatar className={classes.avatar}>
            <LockOutlinedIcon />
          </Avatar>
          <Typography component="h1" variant="h5">
            Sign in
          </Typography>
          <form className={classes.form} noValidate>
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              id="email"
              label="Email Address"
              name="email"
              autoComplete="email"
              autoFocus
            />
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              name="password"
              label="Password"
              type="password"
              id="password"
              autoComplete="current-password"
            />
            <FormControlLabel
              control={<Checkbox value="remember" color="primary" />}
              label="Remember me"
            />
            <Button
              type="submit"
              fullWidth
              variant="contained"
              color="primary"
              className={classes.submit}
            >
              Sign In
            </Button>
            <Grid container>
              <Grid item xs>
                <Link href="/reset-password" variant="body2">
                  Forgot password?
                </Link>
              </Grid>
              <Grid item>
                <Link href="/register" variant="body2">
                  {"Don't have an account? Sign Up"}
                </Link>
              </Grid>
            </Grid>
          </form>
        </div>
      </Container>
    );
  }
}

// 'styles' here produces a
**/*
Argument of type '(props?: any) => Record<"paper" | "avatar" | "form" | "submit", string>' is not assignable to parameter of type 'Styles<Theme, {}, "paper" | "avatar" | "form" | "submit">'.
  Type '(props?: any) => Record<"paper" | "avatar" | "form" | "submit", string>' is not assignable to type 'StyleRulesCallback<Theme, {}, "paper" | "avatar" | "form" | "submit">'.
    Call signature return types 'Record<"paper" | "avatar" | "form" | "submit", string>' and 'Record<"paper" | "avatar" | "form" | "submit", CSSProperties | CreateCSSProperties<{}> | PropsFunc<{}, CreateCSSProperties<{}>>>' are incompatible.
      The types of 'paper' are incompatible between these types.
        Type 'string' is not assignable to type 'CSSProperties | CreateCSSProperties<{}> | PropsFunc<{}, CreateCSSProperties<{}>>'.ts(2345)
*/**
export default withStyles(styles)(LoginPage);
1
  • See my updated answer below. Commented Nov 11, 2020 at 17:49

2 Answers 2

2

I'm also new to React Material-UI with TypeScript and I struggled with the same problems. See this working example: AppBarSample.tsx.

You should add some type definitons:

  1. const styles = makeStyles((theme) => ({
    → 
    const styles: Styles<Theme, {}, string> = (theme: Theme) => ({
    
  2. class LoginPage extends React.Component {
    →
    interface IProps {
      classes?: any;
    }
    class LoginPage extends React.Component<IProps, any> {
    

See this diff and working implementation for more information.

Sign up to request clarification or add additional context in comments.

Comments

0

The error is makeStyles returns a hook and is not to be used with withStyles.

For your Higher Order Component (HOC: LoginPage), you should follow the styles API like this:

replace

   const styles = makeStyles((theme) => ({
    paper: {
     marginTop: theme.spacing(8),...

with

    const styles = {
     paper: {
      marginTop: theme.spacing(8),...

withStyles accepts an object of type CSSProperties as parameter, not a string. makeStyles returns a className.

Good luck, and please do tell me if i solved your issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.