Skip to content

Dealing with CSS Variable Errors in React TypeScript

A while back, I ran into a bit of a headache while working on a project.

2 min read
React
TypeScript
CSS
Custom Properties

A while back, I ran into a bit of a headache while working on a project. It was a simple issue, but it was enough to break my flow. I was trying to use CSS custom properties, or CSS variables, directly inside the inline styles of a React component.

The plan was straightforward: I wanted to create some dynamic styles, mostly for handling themes or changing colors based on a component's state. But the moment I wrote the code, TypeScript started complaining. I kept getting errors saying those properties weren't recognized within the CSSProperties interface.

The weird part was that the app actually worked perfectly fine at runtime. There was no actual issue, but the constant red squiggles in my editor were getting annoying. It turns out React's built-in type definitions just don't account for our own custom CSS variables.

My first instinct was to just use any to get it over with, but I'm not a big fan of that. I prefer using TypeScript when the typing system actually feels precise. I wanted a way to keep using these variables without throwing away type safety.

The solution I found was to augment React's CSSProperties interface. I created a new declaration file, something like src/types/react-augmentations.d.ts, and added a bit of code to extend the interface so it accepts any string key starting with --. Then, I just had to make sure that directory was included in my tsconfig.json.

Once that was done, things were much smoother. I could write code like <div style={{ '--main-color': props.color } as React.CSSProperties}> without much friction. It’s been a huge help for building dynamic theme systems.

I did try another approach where I defined every single CSS variable name explicitly to be even more type-safe, only allowing things like --brand-color or --bg-primary. But honestly, that felt too restrictive. When it comes to CSS, you need a bit of freedom. It makes more sense to let CSS variables work the way they were intended, as long as TypeScript stops flagging them as errors.

Not everything needs to be wrapped in incredibly rigid type rules, but giving these custom variables some breathing room has made my workflow much more comfortable. Of course, this approach has its downsides if you don't keep your project structure organized, but overall, it's been a lifesaver.

I'll leave it there.