13

I'm trying to migrate some of my React components to the new makeStyles/useStyles hook API from Material UI. If I understand correctly I can keep accepting classes as a prop from parent components as long as I pass the props to useStyles:

const MyComponent = (props: Props) => {
  const { myProp } = props;
  const classes = useStyles(props);

I was wondering how to declare my Props type in that case. The equivalent with the HOC API being:

const styles = createStyles({
  a: {},
  b: {}
});

interface Props extends WithStyles<typeof styles> {
  myProp: string;
}

Here is something that works but looks a bit verbose:

const styles = createStyles({
  a: {},
  b: {}
});

interface Props extends StyledComponentProps<ClassKeyOfStyles<typeof styles>> {
  myProp: string;
}

const useStyles = makeStyles(styles);

Is there a better way? Ideally without the need for createStyles and using makeStyles inline with the styles declaration.

2
  • I'm looking for the same thing. Did you find a better way to do this? Commented Apr 28, 2020 at 22:10
  • 1
    @rareyesdev unfortunately I'm still using my very verbose version Commented Apr 30, 2020 at 13:50

2 Answers 2

13

To know at compile time which properties/classes were declared, I used such workaround.

import React from 'react';
import { Theme, makeStyles } from '@material-ui/core';
import { BaseCSSProperties } from '@material-ui/core/styles/withStyles';

interface StyleProps {
    root: BaseCSSProperties,
}

type PropsClasses = Record<keyof StyleProps, string>

let baseStyle: StyleProps = {
    root: {
        color: "red",
    },
};

const useStyles = makeStyles<Theme, StyleProps>(() => baseStyle as any);

const MyComponent = () => {
    const classes: PropsClasses = useStyles({} as StyleProps);
    return (<div className={classes.root}>This is root!</div>)
}

export default MyComponent;

Key moment here - do not forget to declare type for the classes constant.

You can reuse this types in other components and have all required information.

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

Comments

1

Since TypeScript 2.8 you have the ReturnType utility type:

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

const myStyles = makeStyles({
  root: {
    margin: '0',
  },
  foo: {
    background: '#f1f1f1',
  },
  bar: {
    marginRight: '12px',
  },
})

type MyStylesType = ReturnType<typeof myStyles>

// use MyStylesType as type

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.