1

So I have a stylesheet like below

const badgeStyle = createStyles({
  badge: {
    borderRadius: "12px",
    padding: "5px 12px",
    textTransform: "uppercase",
    fontSize: "10px",
    fontWeight: 700,
    lineHeight: 1,
    color: whiteColor,
    textAlign: "center",
    verticalAlign: "baseline",
    display: "inline-block"
  },
  primary: {
    backgroundColor: primaryColor[0]
  },
  warning: {
    backgroundColor: warningColor[0]
  },
  danger: {
    backgroundColor: dangerColor[0]
  },
  success: {
    backgroundColor: successColor[0]
  },
  info: {
    backgroundColor: infoColor[0]
  },
  rose: {
    backgroundColor: roseColor[0]
  },
  gray: {
    backgroundColor: grayColor[0]
  }
});

I import that stylesheet and want you use that line below

import styles from "../../assets/jss/material-dashboard-pro-react/components/badgeStyle";

const useStyles = makeStyles(styles);
const classes = useStyles();
return (
    <span className={classes.badge + " " + classes[color]}>{children}</span>
  );

but this statement classes[color] gives me below error

Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'Record<"badge" | "gray" | "primary" | "warning" | "danger" | "success" | "info" | "rose", string>'

How to use classes[color] in typescript ?

AMendis
  • 1,346
  • 4
  • 18
  • 34

1 Answers1

0

So a solution here could be something like this:

In your stylesheet file:

const bgColors = {
    primary: primaryColor[0],
    warning: warningColor[0],
    danger: dangerColor[0],
    success: successColor[0],
    info: infoColor[0],
    rose: roseColor[0],
    gray: grayColor[0]
}

export type bgColorKey = keyof typeof bgColors;

interface Props {
    color: bgColorKey;
}

export const badgeStyles = createStyles({
    badge: ({ color }: Props) => ({
        borderRadius: "12px",
        padding: "5px 12px",
        textTransform: "uppercase",
        fontSize: "10px",
        fontWeight: 700,
        lineHeight: 1,
        color: whiteColor,
        textAlign: "center",
        verticalAlign: "baseline",
        display: "inline-block",
        backgroundColor: bgColors[color]
    })
});

What I did here is to list all the colors mapping in a separate object bgColors (which really could take place in an assets folder in root folder), that you can access in your stylesheet.

Then you have to declare a type bgColorKey which will be used to type the color variable in order to index bgColors. It's simply a keyof typeof bgColors which basically tells typescript "take the type of my object bgColors and make a union of all its keys as strings".

The thing to know here is that you can pass props to useStyles, in order to make some dynamic styling. So in you badge section of your stylesheet, we pass a callback which takes props as parameters, inside those props we have the color property from your component (which is of type bgColorKey which is the union of "primary", "warning", "rose", and so on).

At that point we simply add backgroundColor: bgColors[color] in the badge section.

So in your component you may have something like this:

export default function MyComponent() {
    const color: bgColorKey = 'primary';

    const useStyles = makeStyles(badgeStyles);
    const classes = useStyles({ color });

    return (
        <span className={classes.badge}>{children}</span>
    )
}

We pass color to useStyles, and your stylesheet will know which color actually correspond to your color variable.

Note that you could get rid of createStyles and export useStyles directly from your stylesheet file like so :

export const useStyles = makeStyles(theme => ({
    badge ({ color }: Props) => ({
        // ...
    })
})

and import it from your component like so:

import useStyles from './styles.tsx';

// ...

const classes = useStyles({ color });
KuroAku
  • 235
  • 1
  • 3
  • 7
  • I managed to solve the problem (which was the same for me with usin the Props on makeStyles hook. From [this thread](https://stackoverflow.com/questions/56111294/how-to-use-theme-and-props-in-makestyles) – Anass Jan 16 '23 at 15:28