I'm having a heck of a time getting my typings correct so I was curious if anyone had a working example or some feedback as to where I am going wrong. There are two things I need to happen with this instance of createUseStyles, accept the theme as well as props.
I took the example from the documentation website, and of course right off the bat its already throwing TypeScript errors, which is understandable:
(pasting screenshot just to show typescript errors)

code block from screenshot:
import React, { ReactNode, CSSProperties } from "react";
import {
createUseStyles,
useTheme,
ThemeProvider,
DefaultTheme,
Styles
} from "react-jss";
interface Props {
children: ReactNode;
useRed: boolean;
}
interface PUTheme {
colorPrimary: string;
altColor: string;
}
const useStyles = createUseStyles({
button: {
background: ({ theme }) => theme.colorPrimary
},
label: {
fontWeight: "bold"
}
});
const Button2: React.FC<Props> = ({ children, ...props }) => {
const theme = useTheme();
console.log(theme);
const classes = useStyles({ ...props, theme });
return (
<button className={classes.button}>
<span className={classes.label}>{children}</span>
</button>
);
};
const theme = {
colorPrimary: "green",
altColor: "red"
};
const App = () => (
<ThemeProvider theme={theme}>
<Button2 useRed={true}>I am a button 2 with green background</Button2>
</ThemeProvider>
);
export default App;
The error found here (Error 1) is:
button: {
background: ({ theme }) => theme.colorPrimary
},
Property 'colorPrimary' does not exist on type 'Theme'.ts(2339)
Makes sense to an extent - it doesn't know what our theme consists of, so moving on...
The error found here (Error 2) for theme is:
const classes = useStyles({ ...props, theme });
Type 'DefaultTheme' is not assignable to type 'Theme'. Type 'null' is not assignable to type 'Theme'.ts(2322)
Right away.. I'm a little confused. But let's type some things and see how it works out...
Adding an interface for my theme doesn't seem to change any of the above errors:
interface PUTheme {
colorPrimary: string;
altColor: string;
}
const theme: PUTheme = {
colorPrimary: "green",
altColor: "red"
};
So since adding an interface to my theme object doesn't seem to accomplish much, I was able to satisfy the error from Error 1 by adding typings. While this calms TypeScript down it feels, wrong?
const useStyles = createUseStyles({
button: {
background: ({ theme }: {theme: PUTheme}) => theme.colorPrimary
},
label: {
fontWeight: "bold"
}
});
However, this still leaves me with Error 2 except the error has changed slightly
Type 'DefaultTheme' is not assignable to type 'PUTheme'. Type 'null' is not assignable to type 'PUTheme'
I've tried following back the typings in react-jss but perhaps this is over my head at the moment.
Does anyone have any tips or insight into what I'm doing wrong or working examples? Also, here is a link to my code sandbox if you wish to see it in action.
I think I've found the solution. The passing of theme/props to the classes still feels strange to me but it works and satisfies TypeScript.
import React, { ReactNode } from "react";
import { createUseStyles, useTheme, ThemeProvider } from "react-jss";
interface Props {
children: ReactNode;
useRed: boolean;
}
interface PUTheme {
colorPrimary: string;
altColor: string;
}
const useStyles = createUseStyles({
button: {
background: ({
theme,
useRed
}: {
theme: PUTheme;
useRed: Props["useRed"];
}) => (useRed ? theme.altColor : theme.colorPrimary)
},
label: {
fontWeight: "bold"
}
});
const Button2: React.FC<Props> = ({ children, ...props }) => {
const theme = useTheme<PUTheme>();
const classes = useStyles({ ...props, theme });
return (
<button className={classes.button}>
<span className={classes.label}>{children}</span>
</button>
);
};
const theme: PUTheme = {
colorPrimary: "green",
altColor: "red"
};
const App = () => (
<ThemeProvider theme={theme}>
<Button2 useRed={true}>I am a button 2 with green background</Button2>
</ThemeProvider>
);
export default App;
The main thing I believe was missing was having useTheme typed const theme = useTheme<PUTheme>();
View working Code Sandbox here!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With