Material-ui: [Typings] The properties of the object for makeStyles aren't typed to CSSProperties

Created on 13 Mar 2019  路  13Comments  路  Source: mui-org/material-ui

The issue is that currently there is no Intellisense or type checking on the properties of the named classes for the object used. So this means anything can be passed. If the properties were typed to CSSProperties that would add more type checking for "valid" CSS and Intellisense.

styles incomplete typescript

Most helpful comment

@TroySchmidt You might be interested in createStyles.

This should have automatic class key inference and css type checks:

const useStyles = makeStyles((theme: Theme) =>
  createStyles({ // <-- this is the important part
    root: {
      color: 'black',
      backgroundColor: 'white',
      display: 'flex',
      flexDirection: 'row',
      alignContent: 'center',
    },
    logo: {
      fontSize: 48,
      height: '0.7em',
      width: 'initial',
      paddingRight: 5,
    },
    avatar: {
      backgroundColor: '#C00000',
      fontSize: '0.65em',
      height: 25,
      width: 25,
    },
    icon: {
      padding: 4,
    },
    paper: {
      '&:hover': {
        backgroundColor: '#c7c7c7',
      },
    },
  }),
);

All 13 comments

Please add an example.

const useStyles = makeStyles((theme: Theme): { [ key: string ]: CSSProperties } => ({
  root: {
    color: 'black',
    backgroundColor: 'white',
    display: 'flex',
    flexDirection: 'row',
    alignContent: 'center',
  },
  logo: {
    fontSize: 48,
    height: '0.7em',
    width: 'initial',
    paddingRight: 5,
  },
  avatar: {
    backgroundColor: '#C00000',
    fontSize: '0.65em',
    height: 25, 
    width: 25
  },
  icon: {
    padding: 4, 
  },
  paper: {
    '&:hover': {
      backgroundColor: '#c7c7c7',
    },
  }
}));

type ClassesProps = ClassNameMap<'root' | 'logo' | 'avatar' | 'icon' | 'paper'>;

const classes = useStyles() as ClassesProps;

Currently I am doing this so that the properties are strongly typed to CSSProperties. If I do this I have to manually type out the classes string options available and cast the useStyles(). If I don't do this then it does infer the class names automatically, but the properties can be whatever.

Admittedly I am no TypeScript typings master so I haven't dug in to the MaterialUI type definitions and see if there is a way to unravel this internally and submit a pull request to fix it.

@TroySchmidt You might be interested in createStyles.

This should have automatic class key inference and css type checks:

const useStyles = makeStyles((theme: Theme) =>
  createStyles({ // <-- this is the important part
    root: {
      color: 'black',
      backgroundColor: 'white',
      display: 'flex',
      flexDirection: 'row',
      alignContent: 'center',
    },
    logo: {
      fontSize: 48,
      height: '0.7em',
      width: 'initial',
      paddingRight: 5,
    },
    avatar: {
      backgroundColor: '#C00000',
      fontSize: '0.65em',
      height: 25,
      width: 25,
    },
    icon: {
      padding: 4,
    },
    paper: {
      '&:hover': {
        backgroundColor: '#c7c7c7',
      },
    },
  }),
);

O M G.... okay yeah documentation is clearly missing on that little nugget. That worked like a charm.

@TroySchmidt Have you read https://material-ui.com/guides/typescript/? The styles accepted by withStyles is the same as accepted by makeStyles. This makes the transition easier since the APIs are similar:

```diff
-const styled = withStyles(styles)
+const useStyles = makeStyles(styles)

-styled(Component);

  • const Component = props => {
  • const classes = useStyles(props)
    +}

I ran into the same issue. Would be nice if makeStyles automatically did the typing magic that createStyles does. However, I created a workaround:

import { StyleRules, makeStyles } from '@material-ui/styles'

export const createStylesHook = <C extends string, P extends object>(styles: StyleRules<P, C>)
  => makeStyles(styles)

Now I get autocomplete for CSS Properties:
image

@geirsagberg Could you open a PR with this change? If this helps autocomplete and doesn't break existing behavior I'm more than happy to merge.

Hi,
What about autocomplete for properties' values:
display: '...' // would suggest none, flex, etc.
Is it possible to make it work?

The justifyContent for example - I am typing from scratch every time

@lishine Do you have a reproduction? It should already be working.

@oliviertassinari Reproduction
You see in this typescript codesandbox that display and justifyContent allow any string, while flexDirection allows specific set of values and does autocomplete.
https://codesandbox.io/s/elegant-cannon-4ff8n?file=/src/App.tsx

@lishine Cool, please see that with https://github.com/frenic/csstype

Was this page helpful?
0 / 5 - 0 ratings