1

I'm writing a React app and I'm using classnames to help with my styling.

I join my classnames like this:

const appBarClasses = classNames({
  [classes.appBar]: true,
  [classes[color]]: color,
  [classes.fixed]: fixed
});

In the line where I set the color TypeScript is complaining:

[ts] Element implicitly has an 'any' type because type 'Record<"fixed" | "appBar" | "primary" | "transparent", string>' has no index signature.

I tried countless variations with as or : string but couldn't get it to work. How do I tell TSLint that this is a string?

Edit: Here is how I obtain classes. I use material-ui for my components and I use it's WithStyles function.

import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import createStyles from "@material-ui/core/styles/createStyles";

export interface Props extends WithStyles<typeof styles> {
  brand: string;
  fixed: boolean;
  changeColorOnScroll: { height: number; color: string };
  color: string;
}

styles is an object created with createStyles.

This is how styles looks:

import createStyles from "@material-ui/core/styles/createStyles";
import { primaryColor } from "../../styles";

const navBarStyle = createStyles({
  appBar: {
    alignItems: "center",
    backgroundColor: "#fff",
    border: "0",
    borderRadius: "3px",
    boxShadow:
      "0 4px 18px 0px rgba(0, 0, 0, 0.12), 0 7px 10px -5px rgba(0, 0, 0, 0.15)",
    color: "#555",
    display: "flex",
    flexFlow: "row nowrap",
    justifyContent: "flex-start",
    marginBottom: "20px",
    padding: "0.625rem 0",
    position: "relative",
    transition: "all 150ms ease 0s",
    width: "100%"
  },
  fixed: {
    position: "fixed"
  },
  primary: {
    backgroundColor: primaryColor,
    boxShadow:
      "0 4px 20px 0px rgba(0, 0, 0, 0.14), 0 7px 12px -5px rgba(156, 39, 176, 0.46)",
    color: "#FFFFFF"
  },
  transparent: {
    backgroundColor: "transparent !important",
    boxShadow: "none",
    color: "#FFFFFF",
    paddingTop: "25px"
  }
});

export default navBarStyle;
J. Hesters
  • 13,117
  • 31
  • 133
  • 249
  • You can always cast `classes` or `color` to `any`, but it might be worth understanding why the compiler thinks `classes[color]` isn't valid. What are the types of `classes` and `color`? – Matt McCutchen Nov 02 '18 at 01:15
  • why are you using `[classes[color]]: color`? And not `[classes.color]: color`? or `[classes[color]]: true`. What type does `classes` have? and of what type is `color`? – Poul Kruijt Nov 02 '18 at 07:58
  • @PierreDuc `[classes[color]]: color` is syntax commonly used with the classnames package (see question for hyperlink). I use it to automatically apply the correct style. The component I wrote has a color prop and this automatically uses the respective color's class. As described in the Props definition, color is of type string and classes are created using `WithStyles` which I believe give a `Record` type. – J. Hesters Nov 02 '18 at 08:06
  • what happens if you cast color to `keyof Record`? – Poul Kruijt Nov 02 '18 at 08:13
  • @PierreDuc Like this: `[classes[color as keyof Record]]: color,` ? Same error – J. Hesters Nov 02 '18 at 08:16
  • @PierreDuc got it to work! You gave the right idea. – J. Hesters Nov 02 '18 at 08:18

1 Answers1

0

I got it to work!

Within the props interface I had to define color like this:

color: "transparent" | "primary";
J. Hesters
  • 13,117
  • 31
  • 133
  • 249